Skip to content

Commit

Permalink
add createRepeatInscriptions method
Browse files Browse the repository at this point in the history
  • Loading branch information
m-aboelenein committed Nov 27, 2023
1 parent ea3e489 commit b39e9aa
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 29 deletions.
1 change: 1 addition & 0 deletions src/capabilities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const extractOrValidateCapabilities = (
signTransaction: validateCapability('signTransaction'),
sendBtcTransaction: validateCapability('sendBtcTransaction'),
createInscription: validateCapability('createInscription'),
createRepeatInscriptions: validateCapability('createRepeatInscriptions'),
};

return Object.entries(capabilityMap).reduce((acc, [capability, value]) => {
Expand Down
30 changes: 1 addition & 29 deletions src/inscriptions/createInscription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,7 @@ import { createUnsecuredToken } from 'jsontokens';

import { getProviderOrThrow } from '../provider';
import { CreateInscriptionOptions, CreateInscriptionPayload } from './types';

const MAX_CONTENT_LENGTH_MAINNET = 400e3; // 400kb is the max miners will mine
const MAX_CONTENT_LENGTH_TESTNET = 60e3; // 60kb limit on Testnet to prevent spam

export const validateInscriptionPayload = (payload: CreateInscriptionPayload) => {
const { contentType, content, payloadType, network, appFeeAddress, appFee } = payload;
if (!/^[a-z]+\/[a-z0-9\-\.\+]+(?=;.*|$)/.test(contentType)) {
throw new Error('Invalid content type detected');
}

if (!content || content.length === 0) {
throw new Error('Empty content not allowed');
}

if (!payloadType || (payloadType !== 'BASE_64' && payloadType !== 'PLAIN_TEXT')) {
throw new Error('Empty invalid payloadType specified');
}

if (
content.length >
(network.type === 'Mainnet' ? MAX_CONTENT_LENGTH_MAINNET : MAX_CONTENT_LENGTH_TESTNET)
) {
throw new Error('Content too large');
}

if ((appFeeAddress?.length ?? 0) > 0 && (appFee ?? 0) <= 0) {
throw new Error('Invalid combination of app fee address and fee provided');
}
};
import { validateInscriptionPayload } from './utils';

export const createInscription = async (options: CreateInscriptionOptions) => {
const { getProvider } = options;
Expand Down
20 changes: 20 additions & 0 deletions src/inscriptions/createRepeatInscriptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { getProviderOrThrow } from 'src/provider';
import { CreateInscriptionOptions, CreateRepeatInscriptionsOptions } from './types';
import { Json, createUnsecuredToken } from 'jsontokens';
import { validateInscriptionPayload } from './utils';

export const createRepeatInscriptions = async (options: CreateRepeatInscriptionsOptions) => {
const { getProvider } = options;
const provider = await getProviderOrThrow(getProvider);

validateInscriptionPayload(options.payload);

try {
const request = createUnsecuredToken(options.payload as unknown as Json);
const response = await provider.createInscription(request);
options.onFinish?.(response);
} catch (error) {
console.error('[Connect] Error during create repeat inscriptions', error);
options.onCancel?.();
}
};
9 changes: 9 additions & 0 deletions src/inscriptions/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export interface CreateInscriptionPayload extends RequestPayload {
token?: string;
}

export interface CreateRepeatInscriptionsPayload extends CreateInscriptionPayload {
repeat: number;
}

export type CreateInscriptionResponse = {
txId: string;
};
Expand All @@ -18,3 +22,8 @@ export type CreateInscriptionOptions = RequestOptions<
CreateInscriptionPayload,
CreateInscriptionResponse
>;

export type CreateRepeatInscriptionsOptions = RequestOptions<
CreateRepeatInscriptionsPayload,
CreateInscriptionResponse
>;
30 changes: 30 additions & 0 deletions src/inscriptions/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { CreateInscriptionPayload } from './types';

const MAX_CONTENT_LENGTH_MAINNET = 400e3; // 400kb is the max miners will mine
const MAX_CONTENT_LENGTH_TESTNET = 60e3; // 60kb limit on Testnet to prevent spam

export const validateInscriptionPayload = (payload: CreateInscriptionPayload) => {
const { contentType, content, payloadType, network, appFeeAddress, appFee } = payload;
if (!/^[a-z]+\/[a-z0-9\-\.\+]+(?=;.*|$)/.test(contentType)) {
throw new Error('Invalid content type detected');
}

if (!content || content.length === 0) {
throw new Error('Empty content not allowed');
}

if (!payloadType || (payloadType !== 'BASE_64' && payloadType !== 'PLAIN_TEXT')) {
throw new Error('Empty invalid payloadType specified');
}

if (
content.length >
(network.type === 'Mainnet' ? MAX_CONTENT_LENGTH_MAINNET : MAX_CONTENT_LENGTH_TESTNET)
) {
throw new Error('Content too large');
}

if ((appFeeAddress?.length ?? 0) > 0 && (appFee ?? 0) <= 0) {
throw new Error('Invalid combination of app fee address and fee provided');
}
};
1 change: 1 addition & 0 deletions src/provider/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface BaseBitcoinProvider {
signTransaction: (request: string) => Promise<SignTransactionResponse>;
sendBtcTransaction: (request: string) => Promise<SendBtcTransactionResponse>;
createInscription: (request: string) => Promise<CreateInscriptionResponse>;
createRepeatInscriptions: (request: string) => Promise<CreateInscriptionResponse>;
}

export type Capability = keyof BaseBitcoinProvider;
Expand Down

0 comments on commit b39e9aa

Please sign in to comment.