diff --git a/.typos.toml b/.typos.toml new file mode 100644 index 0000000..dfb2ddd --- /dev/null +++ b/.typos.toml @@ -0,0 +1,2 @@ +[files] +extend-exclude = ["bun.lockb"] diff --git a/wrappers/fedimint-ts/.eslintrc.json b/wrappers/fedimint-ts/.eslintrc.json new file mode 100644 index 0000000..0682099 --- /dev/null +++ b/wrappers/fedimint-ts/.eslintrc.json @@ -0,0 +1,17 @@ +{ + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], + "rules": { + "@typescript-eslint/no-unused-vars": [ + "warn", + { "varsIgnorePattern": "^_", "argsIgnorePattern": "^_" } + ], + "padding-line-between-statements": [ + "warn", + { "blankLine": "always", "prev": "*", "next": "return" }, + { "blankLine": "always", "prev": "import", "next": "*" }, + { "blankLine": "never", "prev": "import", "next": "import" }, + { "blankLine": "always", "prev": "*", "next": "if" } + ] + } +} diff --git a/wrappers/fedimint-ts/.gitignore b/wrappers/fedimint-ts/.gitignore new file mode 100644 index 0000000..9b1ee42 --- /dev/null +++ b/wrappers/fedimint-ts/.gitignore @@ -0,0 +1,175 @@ +# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore + +# Logs + +logs +_.log +npm-debug.log_ +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Caches + +.cache + +# Diagnostic reports (https://nodejs.org/api/report.html) + +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover + +lib-cov + +# Coverage directory used by tools like istanbul + +coverage +*.lcov + +# nyc test coverage + +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release + +# Dependency directories + +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +*.tsbuildinfo + +# Optional npm cache directory + +.npm + +# Optional eslint cache + +.eslintcache + +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +*.tgz + +# Yarn Integrity file + +.yarn-integrity + +# dotenv environment variable files + +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) + +.parcel-cache + +# Next.js build output + +.next +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + +# Stores VSCode versions used for testing VSCode extensions + +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/wrappers/fedimint-ts/FedimintClient.ts b/wrappers/fedimint-ts/FedimintClient.ts new file mode 100644 index 0000000..ac89cff --- /dev/null +++ b/wrappers/fedimint-ts/FedimintClient.ts @@ -0,0 +1,412 @@ +import type { + BackupRequest, + InfoResponse, + ListOperationsRequest, + FederationIdsResponse, + OperationOutput, +} from "./types/common"; +import type { + AwaitInvoiceRequest, + AwaitLnPayRequest, + Gateway, + LnInvoiceRequest, + LnInvoiceResponse, + LnPayRequest, + LnPayResponse, + SwitchGatewayRequest, +} from "./types/modules/ln"; +import type { + CombineRequest, + CombineResponse, + ReissueRequest, + ReissueResponse, + SpendRequest, + SpendResponse, + SplitRequest, + SplitResponse, + ValidateRequest, + ValidateResponse, +} from "./types/modules/mint"; +import type { + AwaitDepositRequest, + AwaitDepositResponse, + DepositAddressRequest, + DepositAddressResponse, + WithdrawRequest, + WithdrawResponse, +} from "./types/modules/wallet"; + +type FedimintResponse = Promise; + +class FedimintClientBuilder { + private baseUrl: string; + private password: string; + private activeFederationId: string; + + constructor() { + this.baseUrl = ""; + this.password = ""; + this.activeFederationId = ""; + } + + setBaseUrl(baseUrl: string): FedimintClientBuilder { + this.baseUrl = baseUrl; + + return this; + } + + setPassword(password: string): FedimintClientBuilder { + this.password = password; + + return this; + } + + setActiveFederationId(federationId: string): FedimintClientBuilder { + this.activeFederationId = federationId; + + return this; + } + + build(): FedimintClient { + if ( + this.baseUrl === "" || + this.password === "" || + this.activeFederationId === "" + ) { + throw new Error("baseUrl, password, and activeFederationId must be set"); + } + + const client = new FedimintClient( + this.baseUrl, + this.password, + this.activeFederationId + ); + + return client; + } +} + +class FedimintClient { + private baseUrl: string; + private password: string; + private activeFederationId: string; + + constructor(baseUrl: string, password: string, activeFederationId: string) { + this.baseUrl = baseUrl + "/fedimint/v2"; + this.password = password; + this.activeFederationId = activeFederationId; + } + + getActiveFederationId(): string { + return this.activeFederationId; + } + + setActiveFederationId(federationId: string) { + this.activeFederationId = federationId; + } + + /** + * Makes a GET request to the `baseURL` at the given `endpoint`. + * Receives a JSON response. + * Automatically ensures a default federation ID is set if needed. + * @param endpoint - The endpoint to make the request to. + */ + private async get(endpoint: string): FedimintResponse { + const res = await fetch(`${this.baseUrl}${endpoint}`, { + method: "GET", + headers: { Authorization: `Bearer ${this.password}` }, + }); + + if (!res.ok) { + throw new Error( + `GET request failed. Status: ${res.status}, Body: ${await res.text()}` + ); + } + + return (await res.json()) as T; + } + + /** + * Makes a POST request to the `baseURL` at the given `endpoint` with the provided `body`. + * Receives a JSON response. + * Automatically ensures a default federation ID is set if needed. + * @param endpoint - The endpoint to make the request to. + * @param body - The body of the request. + */ + private async post(endpoint: string, body: any): FedimintResponse { + const res = await fetch(`${this.baseUrl}${endpoint}`, { + method: "POST", + headers: { + Authorization: `Bearer ${this.password}`, + "Content-Type": "application/json", + }, + body: JSON.stringify(body), + }); + + if (!res.ok) { + throw new Error( + `POST request failed. Status: ${res.status}, Body: ${await res.text()}` + ); + } + + return (await res.json()) as T; + } + + // Adjust postWithId to not require federationId as a mandatory parameter + // since ensureactiveFederationId will ensure it's set. + private async postWithId( + endpoint: string, + body: any, + federationId?: string + ): FedimintResponse { + // Note: No need to call ensureactiveFederationId here since post already does. + const effectiveFederationId = federationId || this.activeFederationId; + + return this.post(endpoint, { + ...body, + federationId: effectiveFederationId, + }); + } + + /** + * Uploads the encrypted snapshot of mint notest to the federation + */ + public async backup( + metadata: BackupRequest, + federationId?: string + ): FedimintResponse { + await this.postWithId("/admin/backup", metadata, federationId); + } + + /** + * Returns the client configurations by federationId + */ + public async config(): FedimintResponse { + return await this.get("/admin/config"); + } + + /** + * Returns the API version to use to communicate with the federation + */ + public async discoverVersion(): FedimintResponse { + return this.get("/admin/discover-version"); + } + + /** + * Returns the current set of connected federation IDs + */ + public async federationIds(): FedimintResponse { + return await this.get("/admin/federation-ids"); + } + + /** + * Fetches wallet information including holdings, tiers, and federation metadata. + */ + public async info(): FedimintResponse { + return await this.get("/admin/info"); + } + + /** + * Joins a federation with an inviteCode + * Returns an array of federation IDs that the client is now connected to + */ + public async join( + inviteCode: string, + setDefault: boolean + ): FedimintResponse { + return await this.post("/admin/join", { + inviteCode, + setDefault, + }); + } + + /** + * Outputs a list of operations that have been performed on the federation + */ + public async listOperations( + request: ListOperationsRequest, + federationId?: string + ): FedimintResponse { + return await this.postWithId( + "/admin/list-operations", + request, + federationId + ); + } + + /** + * A Module for interacting with Lightning + */ + public ln = { + /** + * Creates a lightning invoice to receive payment via gateway + */ + createInvoice: async ( + request: LnInvoiceRequest, + federationId?: string + ): FedimintResponse => + await this.postWithId( + "/ln/invoice", + request, + federationId + ), + + /** + * Waits for a lightning invoice to be paid + */ + awaitInvoice: async ( + request: AwaitInvoiceRequest, + federationId?: string + ): FedimintResponse => + await this.postWithId( + "/ln/await-invoice", + request, + federationId + ), + + /** + * Pays a lightning invoice or lnurl via a gateway + */ + pay: async ( + request: LnPayRequest, + 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", + 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 + */ + public wallet = { + /** + * Creates a new bitcoin deposit address + */ + createDepositAddress: async ( + request: DepositAddressRequest, + federationId?: string + ): FedimintResponse => + await this.postWithId( + "/wallet/deposit-address", + request, + federationId + ), + + /** + * Waits for a bitcoin deposit to be confirmed + */ + awaitDeposit: async ( + request: AwaitDepositRequest, + federationId?: string + ): FedimintResponse => + await this.postWithId( + "/wallet/await-deposit", + request, + federationId + ), + + /** + * Withdraws bitcoin from the federation + */ + withdraw: async ( + request: WithdrawRequest, + federationId?: string + ): FedimintResponse => + await this.postWithId( + "/wallet/withdraw", + request, + federationId + ), + }; + + /** + * A module for interacting with an ecash mint + */ + public mint = { + /** + * Reissues an ecash note + */ + reissue: async ( + request: ReissueRequest, + federationId?: string + ): FedimintResponse => + await this.postWithId( + "/mint/reissue", + request, + federationId + ), + + /** + * Spends an ecash note + */ + spend: async ( + request: SpendRequest, + federationId?: string + ): FedimintResponse => + await this.postWithId( + "/mint/spend", + request, + federationId + ), + + /** + * Validates an ecash note + */ + validate: async ( + request: ValidateRequest, + federationId?: string + ): FedimintResponse => + await this.postWithId( + "/mint/validate", + 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), + }; +} + +export { FedimintClientBuilder, FedimintClient }; diff --git a/wrappers/fedimint-ts/FedimintUtils.ts b/wrappers/fedimint-ts/FedimintUtils.ts new file mode 100644 index 0000000..e69de29 diff --git a/wrappers/fedimint-ts/README.md b/wrappers/fedimint-ts/README.md new file mode 100644 index 0000000..b1992db --- /dev/null +++ b/wrappers/fedimint-ts/README.md @@ -0,0 +1,91 @@ +# Fedimint SDK in Typescript + +This is a TypeScript client that consumes the [Fedimint Http Client](https://github.com/kodylow/fedimint-http), communicating with it via HTTP and a password. It's a hacky prototype, but it works until we can get a proper TS client for Fedimint. All of the federation handling code happens in the fedimint-http-client, this just exposes a simple API for interacting with the client from TypeScript (will be mirrored in Python and Go). + +## Usage +```typescript +import {FedimintClientBuilder} from "./FedimintClient"; +import dotenv from "dotenv"; + +dotenv.config(); + +const baseUrl = process.env.BASE_URL || "http://localhost:3000"; +const password = process.env.PASSWORD || "password"; +const builder = new FedimintClientBuilder(); +builder.setBaseUrl(baseUrl).setPassword(password); + +// If you pass in an invite code, it will be set as the default federation +if (process.env.INVITE_CODE) { + builder.setInviteCode(process.env.INVITE_CODE); +} + +// The FedimintClient has a default federationId set that it'll call any module methods on +const fedimintClient = await builder.build(); + +// You can update the federationId to call methods on a different federation +const { federation_ids } = await fedimintClient.federationIds(); +await fedimintClient.setDefaultFederationId(federation_ids[0]); + +// Any methods that call on a specific federation can optionally take a federationId as the last argument +// If no federationId is passed, the default federationId is used +const _ = await fedimintClient.listOperations({ limit: 10 }, federation_ids[1]); + +// Admin methods give summaries by federation +fedimintClient.info().then((response) => { + console.log("Current Total Msats Ecash: ", response.total_amount_msat); +}); + +// All module methods are called on the default federationId if you don't pass in a federationId +const { operation_id, invoice } = await fedimintClient.ln.createInvoice({ + amount_msat: 10000, + description: "test", +}); + +console.log("Created 10 sat Invoice: ", invoice); + +console.log("Waiting for payment..."); + +fedimintClient.ln.awaitInvoice({ operation_id }).then((response) => { + console.log("Payment Received!"); + console.log("New Total Msats Ecash: ", response.total_amount_msat); +}); +``` + +# Setup + +Set the following in the fedimint-http .env environment variables: + +```bash +FEDERATION_INVITE_CODE = 'fed1-some-invite-code' +SECRET_KEY = 'some-secret-key' # generate this with `openssl rand -base64 32` +FM_DB_PATH = '/absolute/path/to/fm.db' # just make this a new dir called `fm_db` in the root of the fedimint-http-client and use the absolute path to thatm it'll create the db file for you on startup +PASSWORD = 'password' +DOMAIN = 'localhost' +PORT = 5000 +BASE_URL = 'http://localhost:5000' +``` + +Then start the fedimint-http-client server: + +```bash +cargo run +``` + +Then you're ready to run the typescript client, which will use the same base url and password as the fedimint-http-client: + +```bash +BASE_URL = 'http://localhost:5000' +PASSWORD = 'password' +``` + +To install dependencies: + +```bash +bun install +``` + +To run (this just runs an example that creates FedimintClient in typescript and creates an invoice): + +```bash +bun run example.ts +``` diff --git a/wrappers/fedimint-ts/bun.lockb b/wrappers/fedimint-ts/bun.lockb new file mode 100755 index 0000000..77f16d4 Binary files /dev/null and b/wrappers/fedimint-ts/bun.lockb differ diff --git a/wrappers/fedimint-ts/example.ts b/wrappers/fedimint-ts/example.ts new file mode 100644 index 0000000..be1220a --- /dev/null +++ b/wrappers/fedimint-ts/example.ts @@ -0,0 +1,42 @@ +import { FedimintClientBuilder } from "fedimint-ts"; +import dotenv from "dotenv"; + +dotenv.config(); + +async function main() { + 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" + ); + + // The FedimintClient has a default federationId set that it'll call any module methods on + const fedimintClient = await builder.build(); + + // You can update the federationId to call methods on a different federation + const { federationIds } = await fedimintClient.federationIds(); + await fedimintClient.setActiveFederationId(federationIds[0]); + + // Any methods that call on a specific federation can optionally take a federationId as the last argument + // If no federationId is passed, the default federationId is used + const _ = await fedimintClient.listOperations( + { limit: 10 }, + federationIds[1] + ); + + // Admin methods give summaries by federation + const response = await fedimintClient.info(); + console.log("Response: ", response); + console.log( + "Current Total Msats Ecash for active federation: ", + response[fedimintClient.getActiveFederationId()].totalAmountMsat + ); + + // // All module methods are called on the default federationId if you don't pass in a federationId +} + +main().catch(console.error); diff --git a/wrappers/fedimint-ts/flake.nix b/wrappers/fedimint-ts/flake.nix new file mode 100644 index 0000000..6786906 --- /dev/null +++ b/wrappers/fedimint-ts/flake.nix @@ -0,0 +1,23 @@ +{ + description = "Fedimint TS SDK"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let pkgs = import nixpkgs { inherit system; }; + in { + devShells = { + default = pkgs.mkShell { + nativeBuildInputs = [ pkgs.bun pkgs.nodejs_20 pkgs.starship ]; + shellHook = '' + bun install + eval "$(starship init bash)" + ''; + }; + }; + }); +} diff --git a/wrappers/fedimint-ts/index.ts b/wrappers/fedimint-ts/index.ts new file mode 100644 index 0000000..7964808 --- /dev/null +++ b/wrappers/fedimint-ts/index.ts @@ -0,0 +1,4 @@ +import { FedimintClient, FedimintClientBuilder } from "./FedimintClient"; +import * as types from "./types"; + +export { FedimintClient, FedimintClientBuilder, types }; diff --git a/wrappers/fedimint-ts/package.json b/wrappers/fedimint-ts/package.json new file mode 100644 index 0000000..f0929d0 --- /dev/null +++ b/wrappers/fedimint-ts/package.json @@ -0,0 +1,23 @@ +{ + "name": "fedimint-ts", + "module": "index.ts", + "type": "module", + "author": "The Fedimint Developers", + "license": "MIT", + "version": "0.2.22", + "description": "A TypeScript Wrapper for the Fedimint HTTP Client", + "scripts": { + "build": "tsc" + }, + "devDependencies": { + "bun-types": "latest", + "@typescript-eslint/eslint-plugin": "^6.13.1", + "@typescript-eslint/parser": "^6.13.1", + "eslint": "^8", + "typescript": "^5.0.0" + }, + "dependencies": { + "dotenv": "^16.3.1", + "fedimint-ts": "^0.2.7" + } +} diff --git a/wrappers/fedimint-ts/tsconfig.json b/wrappers/fedimint-ts/tsconfig.json new file mode 100644 index 0000000..a3944af --- /dev/null +++ b/wrappers/fedimint-ts/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "lib": ["ESNext"], + "module": "esnext", + "target": "esnext", + "moduleResolution": "bundler", + "moduleDetection": "force", + "allowImportingTsExtensions": true, + "noEmit": true, + "composite": true, + "strict": true, + "downlevelIteration": true, + "skipLibCheck": true, + "jsx": "react-jsx", + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "allowJs": true, + "declaration": true, + "types": [ + "bun-types" // add Bun global + ] + } +} diff --git a/wrappers/fedimint-ts/types.ts b/wrappers/fedimint-ts/types.ts new file mode 100644 index 0000000..0038358 --- /dev/null +++ b/wrappers/fedimint-ts/types.ts @@ -0,0 +1,252 @@ +interface Tiered { + [amount: number]: T; +} + +interface TieredSummary { + tiered: Tiered; +} + +interface InfoResponse { + federationId: string; + network: string; + meta: { [key: string]: string }; + totalAmountMsat: number; + totalNumNotes: number; + denominationsMsat: TieredSummary; +} + +interface BackupRequest { + metadata: { [key: string]: string }; +} + +interface ListOperationsRequest { + limit: number; +} + +interface OperationOutput { + id: string; + creationTime: string; + operationKind: string; + operationMeta: any; + outcome?: any; +} + +interface DepositAddressRequest { + timeout: number; +} + +interface DepositAddressResponse { + operationId: string; + address: string; +} + +interface AwaitDepositRequest { + operationId: string; +} + +interface BTCInput { + previous_output: string; + script_sig: string; + sequence: number; + witness: string[]; +} + +interface BTCOutput { + value: number; + script_pubkey: string; +} + +interface BTCTransaction { + version: number; + lock_time: number; + input: BTCInput[]; + output: BTCOutput[]; +} + +interface AwaitDepositResponseConfirmed { + btc_transaction: BTCTransaction; + out_idx: number; +} + +interface AwaitDepositResponse { + status: { Confirmed: AwaitDepositResponseConfirmed } | { Failed: string }; +} + +interface WithdrawRequest { + address: string; + amountMsat: number | "all"; +} + +interface WithdrawResponse { + txid: string; + feesSat: number; +} + +interface LnInvoiceRequest { + amountMsat: number; + description: string; + expiryTime?: number; +} + +interface LnInvoiceResponse { + operationId: string; + invoice: string; +} + +interface AwaitInvoiceRequest { + operationId: string; +} + +interface LnPayRequest { + paymentInfo: string; + amountMsat?: number; + finishInBackground: boolean; + lnurlComment?: string; +} + +interface LnPayResponse { + operationId: string; + paymentType: string; + contractId: string; + fee: number; +} + +interface AwaitLnPayRequest { + operationId: string; +} + +interface Gateway { + nodePubKey: string; + active: boolean; +} + +interface SwitchGatewayRequest { + gatewayId: string; +} + +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; +} + +interface ReissueRequest { + notes: OOBNotes; +} + +interface ReissueResponse { + amountMsat: number; +} + +interface SpendRequest { + amountMsat: number; + allowOverpay: boolean; + timeout: number; +} + +interface SpendResponse { + operation: string; + notes: OOBNotes; +} + +interface ValidateRequest { + notes: OOBNotes; +} + +interface ValidateResponse { + amountMsat: number; +} + +interface SplitRequest { + notes: OOBNotes; +} + +interface SplitResponse { + notes: Record; +} + +interface CombineRequest { + notes: OOBNotes[]; +} + +interface CombineResponse { + notes: OOBNotes; +} + +export type { + Tiered, + TieredSummary, + InfoResponse, + BackupRequest, + ListOperationsRequest, + OperationOutput, + DepositAddressRequest, + DepositAddressResponse, + AwaitDepositRequest, + AwaitDepositResponse, + WithdrawRequest, + WithdrawResponse, + LnInvoiceRequest, + LnInvoiceResponse, + AwaitInvoiceRequest, + LnPayRequest, + LnPayResponse, + AwaitLnPayRequest, + Gateway, + SwitchGatewayRequest, + ReissueRequest, + ReissueResponse, + SpendRequest, + SpendResponse, + ValidateRequest, + ValidateResponse, + SplitRequest, + SplitResponse, + CombineRequest, + CombineResponse, +}; diff --git a/wrappers/fedimint-ts/types/common.ts b/wrappers/fedimint-ts/types/common.ts new file mode 100644 index 0000000..bfaaca7 --- /dev/null +++ b/wrappers/fedimint-ts/types/common.ts @@ -0,0 +1,47 @@ +interface Tiered { + [amount: number]: T; +} + +interface TieredSummary { + tiered: Tiered; +} + +interface InfoResponse { + [federationId: string]: { + network: string; + meta: { [key: string]: string }; + totalAmountMsat: number; + totalNumNotes: number; + denominationsMsat: TieredSummary; + }; +} + +interface BackupRequest { + metadata: { [key: string]: string }; +} + +interface ListOperationsRequest { + limit: number; +} + +interface FederationIdsResponse { + federationIds: string[]; +} + +interface OperationOutput { + id: string; + creationTime: string; + operationKind: string; + operationMeta: any; + outcome?: any; +} + +export type { + Tiered, + TieredSummary, + InfoResponse, + BackupRequest, + ListOperationsRequest, + FederationIdsResponse, + OperationOutput, +} diff --git a/wrappers/fedimint-ts/types/modules/ln.ts b/wrappers/fedimint-ts/types/modules/ln.ts new file mode 100644 index 0000000..ab44599 --- /dev/null +++ b/wrappers/fedimint-ts/types/modules/ln.ts @@ -0,0 +1,57 @@ +interface LnInvoiceRequest { + amountMsat: number; + description: string; + expiryTime?: number; +} + +interface LnInvoiceResponse { + operationId: string; + invoice: string; +} + +interface AwaitInvoiceRequest { + operationId: string; +} + +interface LnPayRequest { + paymentInfo: string; + amountMsat?: number; + finishInBackground: boolean; + lnurlComment?: string; +} + +interface LnPayResponse { + operationId: string; + paymentType: string; + contractId: string; + fee: number; +} + +interface AwaitLnPayRequest { + operationId: string; +} + +interface Gateway { + nodePubKey: string; + active: boolean; +} + +interface ListGatewaysResponse { + [federationId: string]: Gateway[]; +} + +interface SwitchGatewayRequest { + gatewayId: string; +} + +export type { + LnInvoiceRequest, + LnInvoiceResponse, + AwaitInvoiceRequest, + LnPayRequest, + LnPayResponse, + AwaitLnPayRequest, + Gateway, + ListGatewaysResponse, + SwitchGatewayRequest, +} diff --git a/wrappers/fedimint-ts/types/modules/mint.ts b/wrappers/fedimint-ts/types/modules/mint.ts new file mode 100644 index 0000000..6e08ea4 --- /dev/null +++ b/wrappers/fedimint-ts/types/modules/mint.ts @@ -0,0 +1,106 @@ +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; +} + +interface ReissueRequest { + notes: string; +} + +interface ReissueResponse { + amountMsat: number; +} + +interface SpendRequest { + amountMsat: number; + allowOverpay: boolean; + timeout: number; +} + +interface SpendResponse { + operation: string; + notes: string; +} + +interface ValidateRequest { + notes: string; +} + +interface ValidateResponse { + amountMsat: number; +} + +interface SplitRequest { + notes: OOBNotes; +} + +interface SplitResponse { + notes: Record; +} + +interface CombineRequest { + notes: string; +} + +interface CombineResponse { + notes: string; +} + +export type { + ReissueRequest, + ReissueResponse, + SpendRequest, + SpendResponse, + ValidateRequest, + ValidateResponse, + SplitRequest, + SplitResponse, + CombineRequest, + CombineResponse, +}; diff --git a/wrappers/fedimint-ts/types/modules/wallet.ts b/wrappers/fedimint-ts/types/modules/wallet.ts new file mode 100644 index 0000000..5746567 --- /dev/null +++ b/wrappers/fedimint-ts/types/modules/wallet.ts @@ -0,0 +1,35 @@ +interface DepositAddressRequest { + timeout: number; +} + +interface DepositAddressResponse { + operationId: string; + address: string; +} + +interface AwaitDepositRequest { + operationId: string; +} + +interface AwaitDepositResponse { + status: string; +} + +interface WithdrawRequest { + address: string; + amountMsat: number | 'all'; +} + +interface WithdrawResponse { + txid: string; + feesSat: number; +} + +export type { + DepositAddressRequest, + DepositAddressResponse, + AwaitDepositRequest, + AwaitDepositResponse, + WithdrawRequest, + WithdrawResponse, +}