Skip to content

Commit

Permalink
Improve APIs and types (BREAKING) (#16)
Browse files Browse the repository at this point in the history
* 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 <victor.kirov@gmail.com>
  • Loading branch information
olistic and victorkirov committed Jul 24, 2023
1 parent 426c35b commit 9f0d3f4
Show file tree
Hide file tree
Showing 19 changed files with 167 additions and 159 deletions.
6 changes: 0 additions & 6 deletions index.ts

This file was deleted.

34 changes: 0 additions & 34 deletions src/address/types.ts

This file was deleted.

9 changes: 5 additions & 4 deletions src/address/index.ts → src/addresses/index.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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?.();
Expand Down
23 changes: 23 additions & 0 deletions src/addresses/types.ts
Original file line number Diff line number Diff line change
@@ -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<GetAddressPayload, GetAddressResponse>;
30 changes: 8 additions & 22 deletions src/call/index.ts
Original file line number Diff line number Diff line change
@@ -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<any>;
}

export interface CallWalletOptions {
getProvider?: GetBitcoinProviderFunc;
onFinish: (response: Record<string, any>) => 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;
Expand All @@ -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';
10 changes: 10 additions & 0 deletions src/call/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { RequestOptions, RequestPayload } from '../types';

export interface CallWalletPayload extends RequestPayload {
method: string;
params?: any[];
}

export type CallWalletResponse = Record<string, any>;

export type CallWalletOptions = RequestOptions<CallWalletPayload, CallWalletResponse>;
6 changes: 6 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export * from './addresses';
export * from './call';
export * from './messages';
export * from './provider';
export * from './transactions';
export * from './types';
5 changes: 3 additions & 2 deletions src/signatures/index.ts → src/messages/index.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
10 changes: 10 additions & 0 deletions src/messages/types.ts
Original file line number Diff line number Diff line change
@@ -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<SignMessagePayload, SignMessageResponse>;
26 changes: 3 additions & 23 deletions src/provider/index.ts
Original file line number Diff line number Diff line change
@@ -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<GetAddressResponse>;
call: (request: string) => Promise<Record<string, any>>;
signTransaction: (request: string) => Promise<SignTransactionResponse>;
signMessage: (request: string) => Promise<string>;
sendBtcTransaction: (request: string) => Promise<string>;
}

declare global {
interface Window {
BitcoinProvider?: BitcoinProvider;
}
}

export type GetBitcoinProviderFunc = () => Promise<BitcoinProvider | undefined>;
import type { BitcoinProvider } from './types';

export async function getDefaultProvider(): Promise<BitcoinProvider | undefined> {
return window.BitcoinProvider;
}

export * from './types';
18 changes: 18 additions & 0 deletions src/provider/types.ts
Original file line number Diff line number Diff line change
@@ -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<CallWalletResponse>;
connect: (request: string) => Promise<GetAddressResponse>;
signMessage: (request: string) => Promise<SignMessageResponse>;
signTransaction: (request: string) => Promise<SignTransactionResponse>;
sendBtcTransaction: (request: string) => Promise<SendBtcTransactionResponse>;
}

declare global {
interface Window {
BitcoinProvider?: BitcoinProvider;
}
}
14 changes: 0 additions & 14 deletions src/signatures/types.ts

This file was deleted.

3 changes: 3 additions & 0 deletions src/transactions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './sendBtcTransaction';
export * from './signTransaction';
export * from './types';
29 changes: 6 additions & 23 deletions src/transactions/sendBtcTransaction.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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?.();
Expand Down
36 changes: 6 additions & 30 deletions src/transactions/signTransaction.ts
Original file line number Diff line number Diff line change
@@ -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<number>;
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;
Expand All @@ -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?.();
Expand Down
42 changes: 42 additions & 0 deletions src/transactions/types.ts
Original file line number Diff line number Diff line change
@@ -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
>;
22 changes: 22 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -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<Payload extends RequestPayload, Response> {
onFinish: (response: Response) => void;
onCancel: () => void;
payload: Payload;
getProvider?: () => Promise<BitcoinProvider | undefined>;
}
Loading

0 comments on commit 9f0d3f4

Please sign in to comment.