From 9f0d3f417416d5979ce531dd8e65f91e0e5ac79a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Olivera?= Date: Mon, 24 Jul 2023 14:21:28 -0600 Subject: [PATCH] Improve APIs and types (BREAKING) (#16) * Remove unused type * Rename AddressPurposes enum for best practices * Extract call types into separate file * Remove unused CallMethod enum * Extract provider types into separate file * Rename directories for consistency * Rename sendBtcTransaction -> sendTransaction * Extract transactions types to separate file * Extract networks module * Improve types * Use [] instead of Array<> for consistency * Fix copy-paste oversight * Move index.ts inside src * Use import type for types * Revert sendBtcTransaction -> sendTransaction renaming * Simplify types --------- Co-authored-by: Victor Kirov --- index.ts | 6 ---- src/address/types.ts | 34 --------------------- src/{address => addresses}/index.ts | 9 +++--- src/addresses/types.ts | 23 ++++++++++++++ src/call/index.ts | 30 +++++------------- src/call/types.ts | 10 ++++++ src/index.ts | 6 ++++ src/{signatures => messages}/index.ts | 5 +-- src/messages/types.ts | 10 ++++++ src/provider/index.ts | 26 ++-------------- src/provider/types.ts | 18 +++++++++++ src/signatures/types.ts | 14 --------- src/transactions/index.ts | 3 ++ src/transactions/sendBtcTransaction.ts | 29 ++++-------------- src/transactions/signTransaction.ts | 36 ++++------------------ src/transactions/types.ts | 42 ++++++++++++++++++++++++++ src/types.ts | 22 ++++++++++++++ tsconfig.json | 1 + webpack.config.js | 2 +- 19 files changed, 167 insertions(+), 159 deletions(-) delete mode 100644 index.ts delete mode 100644 src/address/types.ts rename src/{address => addresses}/index.ts (73%) create mode 100644 src/addresses/types.ts create mode 100644 src/call/types.ts create mode 100644 src/index.ts rename src/{signatures => messages}/index.ts (85%) create mode 100644 src/messages/types.ts create mode 100644 src/provider/types.ts delete mode 100644 src/signatures/types.ts create mode 100644 src/transactions/index.ts create mode 100644 src/transactions/types.ts create mode 100644 src/types.ts diff --git a/index.ts b/index.ts deleted file mode 100644 index 9b1cc9c..0000000 --- a/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './src/address/index'; -export * from './src/call'; -export * from './src/provider'; -export * from './src/signatures'; -export * from './src/transactions/sendBtcTransaction'; -export * from './src/transactions/signTransaction'; diff --git a/src/address/types.ts b/src/address/types.ts deleted file mode 100644 index 5b04b44..0000000 --- a/src/address/types.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { BitcoinNetwork, GetBitcoinProviderFunc } from '../provider'; - -export enum AddressPurposes { - PAYMENT = 'payment', - ORDINALS = 'ordinals', -} - -export interface Purpose { - derivation_path?: string; - purpose: AddressPurposes; -} - -export interface GetAddressPayload { - purposes: Array; - message: string; - network: BitcoinNetwork; -} - -export interface Address { - address: string; - publicKey: string; - purpose: AddressPurposes; -} - -export interface GetAddressResponse { - addresses: Array
; -} - -export interface GetAddressOptions { - getProvider?: GetBitcoinProviderFunc; - onFinish: (response: GetAddressResponse) => void; - onCancel: () => void; - payload: GetAddressPayload; -} diff --git a/src/address/index.ts b/src/addresses/index.ts similarity index 73% rename from src/address/index.ts rename to src/addresses/index.ts index 623d7cf..0b3cf1f 100644 --- a/src/address/index.ts +++ b/src/addresses/index.ts @@ -1,7 +1,8 @@ -import { createUnsecuredToken, Json } from 'jsontokens'; +import type { Json } from 'jsontokens'; +import { createUnsecuredToken } from 'jsontokens'; import { getDefaultProvider } from '../provider'; -import { GetAddressOptions } from './types'; +import type { GetAddressOptions } from './types'; export const getAddress = async (options: GetAddressOptions) => { const { getProvider = getDefaultProvider } = options; @@ -17,8 +18,8 @@ export const getAddress = async (options: GetAddressOptions) => { try { const request = createUnsecuredToken(options.payload as unknown as Json); - const addressResponse = await provider.connect(request); - options.onFinish?.(addressResponse); + const response = await provider.connect(request); + options.onFinish?.(response); } catch (error) { console.error('[Connect] Error during address request', error); options.onCancel?.(); diff --git a/src/addresses/types.ts b/src/addresses/types.ts new file mode 100644 index 0000000..883cd05 --- /dev/null +++ b/src/addresses/types.ts @@ -0,0 +1,23 @@ +import type { RequestOptions, RequestPayload } from '../types'; + +export enum AddressPurpose { + Ordinals = 'ordinals', + Payment = 'payment', +} + +export interface GetAddressPayload extends RequestPayload { + purposes: AddressPurpose[]; + message: string; +} + +export interface Address { + address: string; + publicKey: string; + purpose: AddressPurpose; +} + +export interface GetAddressResponse { + addresses: Address[]; +} + +export type GetAddressOptions = RequestOptions; diff --git a/src/call/index.ts b/src/call/index.ts index 7401e62..5b47664 100644 --- a/src/call/index.ts +++ b/src/call/index.ts @@ -1,24 +1,8 @@ -import { createUnsecuredToken, Json } from 'jsontokens'; +import type { Json } from 'jsontokens'; +import { createUnsecuredToken } from 'jsontokens'; -import { BitcoinNetwork, GetBitcoinProviderFunc, getDefaultProvider } from '../provider'; - -export interface CallWalletPayload { - method: string; - network: BitcoinNetwork; - params?: Array; -} - -export interface CallWalletOptions { - getProvider?: GetBitcoinProviderFunc; - onFinish: (response: Record) => void; - onCancel: () => void; - payload: CallWalletPayload; -} - -export enum CallMethod { - SIGN_TRANSACTION = 'signTransaction', - GET_ADDRESS = 'getAddress', -} +import { getDefaultProvider } from '../provider'; +import type { CallWalletOptions } from './types'; export const callWalletPopup = async (options: CallWalletOptions) => { const { getProvider = getDefaultProvider } = options; @@ -34,10 +18,12 @@ export const callWalletPopup = async (options: CallWalletOptions) => { const request = createUnsecuredToken(options.payload as unknown as Json); try { - const callResponse = await provider.call(request); - options.onFinish?.(callResponse); + const response = await provider.call(request); + options.onFinish?.(response); } catch (error) { console.error('[Connect] Error during call request', error); options.onCancel?.(); } }; + +export * from './types'; diff --git a/src/call/types.ts b/src/call/types.ts new file mode 100644 index 0000000..ba82bca --- /dev/null +++ b/src/call/types.ts @@ -0,0 +1,10 @@ +import type { RequestOptions, RequestPayload } from '../types'; + +export interface CallWalletPayload extends RequestPayload { + method: string; + params?: any[]; +} + +export type CallWalletResponse = Record; + +export type CallWalletOptions = RequestOptions; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..e402881 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,6 @@ +export * from './addresses'; +export * from './call'; +export * from './messages'; +export * from './provider'; +export * from './transactions'; +export * from './types'; diff --git a/src/signatures/index.ts b/src/messages/index.ts similarity index 85% rename from src/signatures/index.ts rename to src/messages/index.ts index 0ad3559..433d805 100644 --- a/src/signatures/index.ts +++ b/src/messages/index.ts @@ -1,7 +1,8 @@ -import { createUnsecuredToken, Json } from 'jsontokens'; +import type { Json } from 'jsontokens'; +import { createUnsecuredToken } from 'jsontokens'; import { getDefaultProvider } from '../provider'; -import { SignMessageOptions } from './types'; +import type { SignMessageOptions } from './types'; export const signMessage = async (options: SignMessageOptions) => { const { getProvider = getDefaultProvider } = options; diff --git a/src/messages/types.ts b/src/messages/types.ts new file mode 100644 index 0000000..5c4baf2 --- /dev/null +++ b/src/messages/types.ts @@ -0,0 +1,10 @@ +import type { RequestOptions, RequestPayload } from '../types'; + +export interface SignMessagePayload extends RequestPayload { + address: string; + message: string; +} + +export type SignMessageResponse = string; + +export type SignMessageOptions = RequestOptions; diff --git a/src/provider/index.ts b/src/provider/index.ts index 834bbae..5640cca 100644 --- a/src/provider/index.ts +++ b/src/provider/index.ts @@ -1,27 +1,7 @@ -import { GetAddressResponse } from '../address'; -import { SignTransactionResponse } from '../transactions/signTransaction'; - -export interface BitcoinNetwork { - type: 'Mainnet' | 'Testnet'; - address?: string; -} - -export interface BitcoinProvider { - connect: (request: string) => Promise; - call: (request: string) => Promise>; - signTransaction: (request: string) => Promise; - signMessage: (request: string) => Promise; - sendBtcTransaction: (request: string) => Promise; -} - -declare global { - interface Window { - BitcoinProvider?: BitcoinProvider; - } -} - -export type GetBitcoinProviderFunc = () => Promise; +import type { BitcoinProvider } from './types'; export async function getDefaultProvider(): Promise { return window.BitcoinProvider; } + +export * from './types'; diff --git a/src/provider/types.ts b/src/provider/types.ts new file mode 100644 index 0000000..5903144 --- /dev/null +++ b/src/provider/types.ts @@ -0,0 +1,18 @@ +import type { GetAddressResponse } from '../addresses'; +import type { CallWalletResponse } from '../call'; +import type { SignMessageResponse } from '../messages'; +import type { SendBtcTransactionResponse, SignTransactionResponse } from '../transactions'; + +export interface BitcoinProvider { + call: (request: string) => Promise; + connect: (request: string) => Promise; + signMessage: (request: string) => Promise; + signTransaction: (request: string) => Promise; + sendBtcTransaction: (request: string) => Promise; +} + +declare global { + interface Window { + BitcoinProvider?: BitcoinProvider; + } +} diff --git a/src/signatures/types.ts b/src/signatures/types.ts deleted file mode 100644 index 67d1424..0000000 --- a/src/signatures/types.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { BitcoinNetwork, GetBitcoinProviderFunc } from '../provider'; - -export interface SignMessagePayload { - address: string; - message: string; - network: BitcoinNetwork; -} - -export interface SignMessageOptions { - getProvider?: GetBitcoinProviderFunc; - onFinish: (response: string) => void; - onCancel: () => void; - payload: SignMessagePayload; -} diff --git a/src/transactions/index.ts b/src/transactions/index.ts new file mode 100644 index 0000000..8fc6c5a --- /dev/null +++ b/src/transactions/index.ts @@ -0,0 +1,3 @@ +export * from './sendBtcTransaction'; +export * from './signTransaction'; +export * from './types'; diff --git a/src/transactions/sendBtcTransaction.ts b/src/transactions/sendBtcTransaction.ts index eca434f..a9b154a 100644 --- a/src/transactions/sendBtcTransaction.ts +++ b/src/transactions/sendBtcTransaction.ts @@ -1,25 +1,8 @@ -import { createUnsecuredToken, Json } from 'jsontokens'; +import type { Json } from 'jsontokens'; +import { createUnsecuredToken } from 'jsontokens'; -import { BitcoinNetwork, GetBitcoinProviderFunc, getDefaultProvider } from '../provider'; - -export interface Recipient { - address: string; - amountSats: bigint; -} - -export interface SendBtcTransactionPayload { - network: BitcoinNetwork; - recipients: Recipient[]; - senderAddress: string; - message?: string; -} - -export interface SendBtcTransactionOptions { - getProvider?: GetBitcoinProviderFunc; - onFinish: (response: string) => void; - onCancel: () => void; - payload: SendBtcTransactionPayload; -} +import { getDefaultProvider } from '../provider'; +import type { SendBtcTransactionOptions } from './types'; export const sendBtcTransaction = async (options: SendBtcTransactionOptions) => { const { getProvider = getDefaultProvider } = options; @@ -38,8 +21,8 @@ export const sendBtcTransaction = async (options: SendBtcTransactionOptions) => try { const request = createUnsecuredToken(options.payload as unknown as Json); - const addressResponse = await provider.sendBtcTransaction(request); - options.onFinish?.(addressResponse); + const response = await provider.sendBtcTransaction(request); + options.onFinish?.(response); } catch (error) { console.error('[Connect] Error during send BTC transaction request', error); options.onCancel?.(); diff --git a/src/transactions/signTransaction.ts b/src/transactions/signTransaction.ts index 8cb303c..03066fa 100644 --- a/src/transactions/signTransaction.ts +++ b/src/transactions/signTransaction.ts @@ -1,32 +1,8 @@ -import { createUnsecuredToken, Json } from 'jsontokens'; +import type { Json } from 'jsontokens'; +import { createUnsecuredToken } from 'jsontokens'; -import { BitcoinNetwork, GetBitcoinProviderFunc, getDefaultProvider } from '../provider'; - -export interface InputToSign { - address: string; - signingIndexes: Array; - sigHash?: number; -} - -export interface SignTransactionPayload { - network: BitcoinNetwork; - message: string; - psbtBase64: string; - broadcast?: boolean; - inputsToSign: InputToSign[]; -} - -export interface SignTransactionOptions { - getProvider?: GetBitcoinProviderFunc; - onFinish: (response: any) => void; - onCancel: () => void; - payload: SignTransactionPayload; -} - -export interface SignTransactionResponse { - psbtBase64: string; - txId?: string; -} +import { getDefaultProvider } from '../provider'; +import type { SignTransactionOptions } from './types'; export const signTransaction = async (options: SignTransactionOptions) => { const { getProvider = getDefaultProvider } = options; @@ -45,8 +21,8 @@ export const signTransaction = async (options: SignTransactionOptions) => { try { const request = createUnsecuredToken(options.payload as unknown as Json); - const addressResponse = await provider.signTransaction(request); - options.onFinish?.(addressResponse); + const response = await provider.signTransaction(request); + options.onFinish?.(response); } catch (error) { console.error('[Connect] Error during sign transaction request', error); options.onCancel?.(); diff --git a/src/transactions/types.ts b/src/transactions/types.ts new file mode 100644 index 0000000..548e3cb --- /dev/null +++ b/src/transactions/types.ts @@ -0,0 +1,42 @@ +import type { RequestOptions, RequestPayload } from '../types'; + +export interface Recipient { + address: string; + amountSats: bigint; +} + +export interface SendBtcTransactionPayload extends RequestPayload { + recipients: Recipient[]; + senderAddress: string; + message?: string; +} + +export type SendBtcTransactionResponse = string; + +export type SendBtcTransactionOptions = RequestOptions< + SendBtcTransactionPayload, + SendBtcTransactionResponse +>; + +export interface InputToSign { + address: string; + signingIndexes: number[]; + sigHash?: number; +} + +export interface SignTransactionPayload extends RequestPayload { + message: string; + psbtBase64: string; + inputsToSign: InputToSign[]; + broadcast?: boolean; +} + +export interface SignTransactionResponse { + psbtBase64: string; + txId?: string; +} + +export type SignTransactionOptions = RequestOptions< + SignTransactionPayload, + SignTransactionResponse +>; diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..2b68fde --- /dev/null +++ b/src/types.ts @@ -0,0 +1,22 @@ +import type { BitcoinProvider } from './provider'; + +export enum BitcoinNetworkType { + Mainnet = 'Mainnet', + Testnet = 'Testnet', +} + +export interface BitcoinNetwork { + type: BitcoinNetworkType; + address?: string; +} + +export interface RequestPayload { + network: BitcoinNetwork; +} + +export interface RequestOptions { + onFinish: (response: Response) => void; + onCancel: () => void; + payload: Payload; + getProvider?: () => Promise; +} diff --git a/tsconfig.json b/tsconfig.json index 282672c..2624399 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,5 +16,6 @@ "allowUnreachableCode": false, "skipLibCheck": true }, + "include": ["./src"], "exclude": ["./tests", "./dist"] } diff --git a/webpack.config.js b/webpack.config.js index 3c32dd9..4181af9 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -8,7 +8,7 @@ const isProduction = process.env.NODE_ENV === NODE_ENV_PRODUCTION; module.exports = { mode: isProduction ? NODE_ENV_PRODUCTION : NODE_ENV_DEVELOPMENT, - entry: ['./index.ts'], + entry: ['./src/index.ts'], output: { filename: 'index.js', library: 'sats_connect',