mirror of
https://github.com/farcasterxyz/hub-monorepo.git
synced 2026-04-18 03:00:22 -04:00
Add syncing/replication example for Postgres (#938)
Provide a working end-to-end example of syncing data from hubs to a Postgres database. This should work with no additional dependencies besides what you install with `yarn install` and Docker.
This commit is contained in:
@@ -6,6 +6,7 @@ contained repository that includes a StackBlitz link to run it in a cloud REPL.
|
||||
- [Generate a chronological feed](./chron-feed/)
|
||||
- [Writing data for a user](./write-data/)
|
||||
- [Building casts correctly](./make-cast/)
|
||||
- [Replicating data into Postgres](./replicate-data-postgres/)
|
||||
|
||||
Other examples that should be added:
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
## Replicate hub data into Postgres
|
||||
|
||||
This example shows you how you can quickly start ingesting data from a Farcaster hub into a traditional database like Postgres.
|
||||
|
||||
### Run on StackBlitz
|
||||
|
||||
[](https://stackblitz.com/github/farcasterxyz/hubble/tree/main/packages/hub-nodejs/examples/replicate-data-postgres)
|
||||
|
||||
### Run locally
|
||||
|
||||
1. Clone the repo locally
|
||||
2. Navigate to this folder with `cd packages/hub-nodejs/examples/replicate-data-postgres`
|
||||
3. Run `yarn install` to install dependencies
|
||||
4. Run `docker compose up -d` to start a Postgres instance ([install Docker](https://docs.docker.com/get-docker/) if you do not yet have it)
|
||||
5. Run `yarn start`
|
||||
|
||||
To wipe your local data, run `docker compose down -v` from this directory.
|
||||
172
packages/hub-nodejs/examples/replicate-data-postgres/db.ts
Normal file
172
packages/hub-nodejs/examples/replicate-data-postgres/db.ts
Normal file
@@ -0,0 +1,172 @@
|
||||
import { Kysely, CamelCasePlugin, Generated, GeneratedAlways, Migrator, FileMigrationProvider } from 'kysely';
|
||||
import { PostgresJSDialect } from 'kysely-postgres-js';
|
||||
import postgres from 'postgres';
|
||||
import { MessageType, ReactionType, UserDataType, HashScheme, SignatureScheme } from '@farcaster/hub-nodejs';
|
||||
import * as path from 'path';
|
||||
import { promises as fs } from 'fs';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { Logger } from './log';
|
||||
import { err, ok, Result } from 'neverthrow';
|
||||
|
||||
export interface Database {
|
||||
hubSubscriptions: {
|
||||
host: string;
|
||||
lastEventId: number;
|
||||
};
|
||||
|
||||
casts: {
|
||||
id: GeneratedAlways<string>;
|
||||
createdAt: Generated<Date>;
|
||||
updatedAt: Generated<Date>;
|
||||
deletedAt: Date | null;
|
||||
timestamp: Date;
|
||||
fid: number;
|
||||
text: string;
|
||||
hash: Uint8Array;
|
||||
parentHash: Uint8Array | null;
|
||||
parentFid: number | null;
|
||||
parentUrl: string | null;
|
||||
embeds: Generated<string[]>;
|
||||
mentions: Generated<number[]>;
|
||||
mentionsPositions: Generated<number[]>;
|
||||
};
|
||||
|
||||
messages: {
|
||||
id: GeneratedAlways<string>;
|
||||
createdAt: Generated<Date>;
|
||||
updatedAt: Generated<Date>;
|
||||
deletedAt: Date | null;
|
||||
revokedAt: Date | null;
|
||||
prunedAt: Date | null;
|
||||
fid: number;
|
||||
messageType: MessageType;
|
||||
timestamp: Date;
|
||||
hash: Uint8Array;
|
||||
hashScheme: HashScheme;
|
||||
signature: Uint8Array;
|
||||
signatureScheme: SignatureScheme;
|
||||
signer: Uint8Array;
|
||||
raw: Uint8Array;
|
||||
};
|
||||
|
||||
reactions: {
|
||||
id: GeneratedAlways<string>;
|
||||
createdAt: Generated<Date>;
|
||||
updatedAt: Generated<Date>;
|
||||
deletedAt: Date | null;
|
||||
fid: number;
|
||||
reactionType: ReactionType;
|
||||
timestamp: Date;
|
||||
hash: Uint8Array;
|
||||
targetHash: Uint8Array | null;
|
||||
targetFid: number | null;
|
||||
targetUrl: string | null;
|
||||
};
|
||||
|
||||
signers: {
|
||||
id: GeneratedAlways<string>;
|
||||
createdAt: Generated<Date>;
|
||||
updatedAt: Generated<Date>;
|
||||
deletedAt: Date | null;
|
||||
timestamp: Date;
|
||||
fid: number;
|
||||
custodyAddress: Uint8Array;
|
||||
signer: Uint8Array;
|
||||
name: string | null;
|
||||
hash: Uint8Array;
|
||||
};
|
||||
|
||||
verifications: {
|
||||
id: GeneratedAlways<string>;
|
||||
createdAt: Generated<Date>;
|
||||
updatedAt: Generated<Date>;
|
||||
deletedAt: Date | null;
|
||||
fid: number;
|
||||
timestamp: Date;
|
||||
hash: Uint8Array;
|
||||
claim: {
|
||||
address: string;
|
||||
ethSignature: string;
|
||||
blockHash: string;
|
||||
};
|
||||
};
|
||||
|
||||
userData: {
|
||||
id: GeneratedAlways<string>;
|
||||
createdAt: Generated<Date>;
|
||||
updatedAt: Generated<Date>;
|
||||
deletedAt: Date | null;
|
||||
timestamp: Date;
|
||||
fid: number;
|
||||
hash: Uint8Array;
|
||||
type: UserDataType;
|
||||
value: string;
|
||||
};
|
||||
|
||||
fids: {
|
||||
fid: number;
|
||||
createdAt: Generated<Date>;
|
||||
updatedAt: Generated<Date>;
|
||||
custodyAddress: Uint8Array;
|
||||
};
|
||||
|
||||
fnames: {
|
||||
fname: string;
|
||||
createdAt: Generated<Date>;
|
||||
updatedAt: Generated<Date>;
|
||||
custodyAddress: Uint8Array;
|
||||
expiresAt: Date;
|
||||
};
|
||||
}
|
||||
|
||||
export const getDbClient = (connectionString: string) => {
|
||||
return new Kysely<Database>({
|
||||
dialect: new PostgresJSDialect({
|
||||
connectionString,
|
||||
options: {
|
||||
max: 10,
|
||||
types: {
|
||||
// BigInts will not exceed Number.MAX_SAFE_INTEGER for our use case.
|
||||
// Return as JavaScript's `number` type so it's easier to work with.
|
||||
bigint: {
|
||||
to: 20,
|
||||
from: 20,
|
||||
parse: (x: any) => Number(x),
|
||||
serialize: (x: any) => x.toString(),
|
||||
},
|
||||
},
|
||||
},
|
||||
postgres,
|
||||
}),
|
||||
plugins: [new CamelCasePlugin()],
|
||||
});
|
||||
};
|
||||
|
||||
export const migrateToLatest = async (db: Kysely<any>, log: Logger): Promise<Result<void, unknown>> => {
|
||||
const migrator = new Migrator({
|
||||
db,
|
||||
provider: new FileMigrationProvider({
|
||||
fs,
|
||||
path,
|
||||
migrationFolder: path.join(path.dirname(fileURLToPath(import.meta.url)), 'migrations'),
|
||||
}),
|
||||
});
|
||||
|
||||
const { error, results } = await migrator.migrateToLatest();
|
||||
|
||||
results?.forEach((it) => {
|
||||
if (it.status === 'Success') {
|
||||
log.info(`migration "${it.migrationName}" was executed successfully`);
|
||||
} else if (it.status === 'Error') {
|
||||
log.error(`failed to execute migration "${it.migrationName}"`);
|
||||
}
|
||||
});
|
||||
|
||||
if (error) {
|
||||
log.error('failed to migrate');
|
||||
log.error(error);
|
||||
return err(error);
|
||||
}
|
||||
|
||||
return ok(undefined);
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
version: '3.9'
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15-alpine # Smaller image for demonstration purposes
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- '6543:5432' # Use a port unlikely to be in use
|
||||
environment:
|
||||
- POSTGRES_DB=hub
|
||||
- POSTGRES_USER=app
|
||||
- POSTGRES_PASSWORD=password
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ['CMD-SHELL', 'pg_isready']
|
||||
interval: 10s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
volumes:
|
||||
pgdata:
|
||||
@@ -0,0 +1,466 @@
|
||||
import {
|
||||
CastAddMessage,
|
||||
CastRemoveMessage,
|
||||
HubRpcClient,
|
||||
IdRegistryEvent,
|
||||
Message,
|
||||
NameRegistryEvent,
|
||||
ReactionAddMessage,
|
||||
ReactionRemoveMessage,
|
||||
SignerAddMessage,
|
||||
SignerRemoveMessage,
|
||||
UserDataAddMessage,
|
||||
VerificationAddEthAddressMessage,
|
||||
VerificationRemoveMessage,
|
||||
isCastAddMessage,
|
||||
isCastRemoveMessage,
|
||||
isMergeIdRegistryEventHubEvent,
|
||||
isMergeMessageHubEvent,
|
||||
isMergeNameRegistryEventHubEvent,
|
||||
isPruneMessageHubEvent,
|
||||
isReactionAddMessage,
|
||||
isReactionRemoveMessage,
|
||||
isRevokeMessageHubEvent,
|
||||
isSignerAddMessage,
|
||||
isSignerRemoveMessage,
|
||||
isUserDataAddMessage,
|
||||
isVerificationAddEthAddressMessage,
|
||||
isVerificationRemoveMessage,
|
||||
getSSLHubRpcClient,
|
||||
getInsecureHubRpcClient,
|
||||
} from '@farcaster/hub-nodejs';
|
||||
import { HubSubscriber } from './hubSubscriber';
|
||||
import { Logger } from 'pino';
|
||||
import { Database } from './db';
|
||||
import { Kysely, sql } from 'kysely';
|
||||
import { bytesToHex, farcasterTimeToDate } from './util';
|
||||
|
||||
type StoreMessageOperation = 'merge' | 'delete' | 'prune' | 'revoke';
|
||||
|
||||
export class HubReplicator {
|
||||
private client: HubRpcClient;
|
||||
private subscriber: HubSubscriber;
|
||||
|
||||
constructor(private hubAddress: string, private ssl: boolean, private db: Kysely<Database>, private log: Logger) {
|
||||
this.client = this.ssl ? getSSLHubRpcClient(hubAddress) : getInsecureHubRpcClient(hubAddress);
|
||||
this.subscriber = new HubSubscriber(this.client, log);
|
||||
|
||||
this.subscriber.on('event', async (hubEvent) => {
|
||||
if (isMergeMessageHubEvent(hubEvent)) {
|
||||
await this.onMergeMessage(hubEvent.mergeMessageBody.message);
|
||||
|
||||
for (const deletedMessage of hubEvent.mergeMessageBody.deletedMessages) {
|
||||
await this.storeMessage(deletedMessage, 'delete');
|
||||
}
|
||||
} else if (isPruneMessageHubEvent(hubEvent)) {
|
||||
await this.onPruneMessage(hubEvent.pruneMessageBody.message);
|
||||
} else if (isRevokeMessageHubEvent(hubEvent)) {
|
||||
await this.onRevokeMessage(hubEvent.revokeMessageBody.message);
|
||||
} else if (isMergeIdRegistryEventHubEvent(hubEvent)) {
|
||||
await this.onIdRegistryEvent(hubEvent.mergeIdRegistryEventBody.idRegistryEvent);
|
||||
} else if (isMergeNameRegistryEventHubEvent(hubEvent)) {
|
||||
await this.onNameRegistryEvent(hubEvent.mergeNameRegistryEventBody.nameRegistryEvent);
|
||||
}
|
||||
|
||||
// Keep track of how many events we've processed.
|
||||
await this.db
|
||||
.insertInto('hubSubscriptions')
|
||||
.values({ host: this.hubAddress, lastEventId: hubEvent.id })
|
||||
.onConflict((oc) =>
|
||||
oc.columns(['host']).doUpdateSet({
|
||||
lastEventId: hubEvent.id,
|
||||
})
|
||||
)
|
||||
.execute();
|
||||
});
|
||||
}
|
||||
|
||||
public async start() {
|
||||
const infoResult = await this.client.getInfo({ syncStats: true });
|
||||
|
||||
if (infoResult.isErr() || infoResult.value.syncStats === undefined) {
|
||||
throw new Error(`Unable to get information about hub ${this.hubAddress}`);
|
||||
}
|
||||
|
||||
const { numMessages } = infoResult.value.syncStats;
|
||||
|
||||
this.log.info(`Syncing ${numMessages} messages from ${this.hubAddress}`);
|
||||
|
||||
// Start backfilling all historical data in the background
|
||||
this.backfill();
|
||||
|
||||
// Process live events going forward, starting from the last event we
|
||||
// processed (if there was one).
|
||||
const subscription = await this.db
|
||||
.selectFrom('hubSubscriptions')
|
||||
.where('host', '=', this.hubAddress)
|
||||
.select('lastEventId')
|
||||
.executeTakeFirst();
|
||||
this.subscriber.start(subscription?.lastEventId);
|
||||
}
|
||||
|
||||
public stop() {
|
||||
this.subscriber.stop();
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this.subscriber.destroy();
|
||||
}
|
||||
|
||||
private async backfill() {
|
||||
const maxFidResult = await this.client.getFids({ pageSize: 1, reverse: true });
|
||||
if (maxFidResult.isErr()) throw new Error('Unable to backfill', { cause: maxFidResult.error });
|
||||
|
||||
const maxFid = maxFidResult.value.fids[0];
|
||||
|
||||
for (let fid = 1; fid <= maxFid; fid++) {
|
||||
this.log.info(`Starting backfill for FID ${fid}`);
|
||||
await this.processAllMessagesForFid(fid);
|
||||
this.log.info(`Completed backfill for FID ${fid}`);
|
||||
}
|
||||
}
|
||||
|
||||
private async processAllMessagesForFid(fid: number) {
|
||||
await this.client
|
||||
.getIdRegistryEvent({ fid })
|
||||
.then((result) => result.map((event) => this.onIdRegistryEvent(event)));
|
||||
|
||||
await this.client
|
||||
.getCastsByFid({ fid })
|
||||
.then((result) => result.map((response) => response.messages.map((message) => this.onMergeMessage(message))));
|
||||
|
||||
await this.client
|
||||
.getReactionsByFid({ fid })
|
||||
.then((result) => result.map((response) => response.messages.map((message) => this.onMergeMessage(message))));
|
||||
|
||||
await this.client
|
||||
.getSignersByFid({ fid })
|
||||
.then((result) => result.map((response) => response.messages.map((message) => this.onMergeMessage(message))));
|
||||
|
||||
await this.client
|
||||
.getVerificationsByFid({ fid })
|
||||
.then((result) => result.map((response) => response.messages.map((message) => this.onMergeMessage(message))));
|
||||
|
||||
await this.client
|
||||
.getUserDataByFid({ fid })
|
||||
.then((result) => result.map((response) => response.messages.map((message) => this.onMergeMessage(message))));
|
||||
}
|
||||
|
||||
// More for demonstration purposes. Can always just get the latest FID
|
||||
private async *getAllFids() {
|
||||
let fidsResult = await this.client.getFids({ pageSize: 1000 });
|
||||
for (;;) {
|
||||
if (fidsResult.isErr()) {
|
||||
throw new Error('Unable to backfill', { cause: fidsResult.error });
|
||||
}
|
||||
|
||||
const { fids, nextPageToken } = fidsResult.value;
|
||||
|
||||
yield fids;
|
||||
|
||||
if (!nextPageToken) break;
|
||||
fidsResult = await this.client.getFids({ pageSize: 1000, pageToken: nextPageToken });
|
||||
}
|
||||
}
|
||||
|
||||
private async storeMessage(message: Message, operation: StoreMessageOperation) {
|
||||
if (!message.data) {
|
||||
throw new Error('Message data is missing');
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
|
||||
const messageRow = await this.db
|
||||
.insertInto('messages')
|
||||
.values({
|
||||
fid: message.data.fid,
|
||||
messageType: message.data.type,
|
||||
timestamp: farcasterTimeToDate(message.data.timestamp),
|
||||
hash: message.hash,
|
||||
hashScheme: message.hashScheme,
|
||||
signature: message.signature,
|
||||
signatureScheme: message.signatureScheme,
|
||||
signer: message.signer,
|
||||
raw: Message.encode(message).finish(),
|
||||
deletedAt: operation === 'delete' ? now : null,
|
||||
prunedAt: operation === 'prune' ? now : null,
|
||||
revokedAt: operation === 'revoke' ? now : null,
|
||||
})
|
||||
.onConflict((oc) =>
|
||||
oc
|
||||
.columns(['hash'])
|
||||
.doUpdateSet({
|
||||
updatedAt: now,
|
||||
// Only the signer or message state could have changed
|
||||
signature: message.signature,
|
||||
signatureScheme: message.signatureScheme,
|
||||
signer: message.signer,
|
||||
deletedAt: operation === 'delete' ? now : null,
|
||||
prunedAt: operation === 'prune' ? now : null,
|
||||
revokedAt: operation === 'revoke' ? now : null,
|
||||
})
|
||||
.where(({ or, cmpr, ref }) =>
|
||||
// Only update if a value has actually changed
|
||||
or([
|
||||
cmpr('excluded.signature', '!=', ref('messages.signature')),
|
||||
cmpr('excluded.signatureScheme', '!=', ref('messages.signatureScheme')),
|
||||
cmpr('excluded.signer', '!=', ref('messages.signer')),
|
||||
cmpr('excluded.deletedAt', 'is', sql`distinct from ${ref('messages.deletedAt')}`),
|
||||
cmpr('excluded.prunedAt', 'is', sql`distinct from ${ref('messages.prunedAt')}`),
|
||||
cmpr('excluded.revokedAt', 'is', sql`distinct from ${ref('messages.revokedAt')}`),
|
||||
])
|
||||
)
|
||||
)
|
||||
.returning(['updatedAt', 'createdAt'])
|
||||
.executeTakeFirst();
|
||||
|
||||
// Return boolean indicating whether this is a new message
|
||||
return !!(messageRow && messageRow.updatedAt === messageRow.createdAt);
|
||||
}
|
||||
|
||||
private async onIdRegistryEvent(event: IdRegistryEvent) {
|
||||
await this.db
|
||||
.insertInto('fids')
|
||||
.values({ fid: event.fid, custodyAddress: event.to })
|
||||
.onConflict((oc) => oc.columns(['fid']).doUpdateSet({ custodyAddress: event.to, updatedAt: new Date() }))
|
||||
.execute();
|
||||
}
|
||||
|
||||
private async onNameRegistryEvent(event: NameRegistryEvent) {
|
||||
const custodyAddress = event.to;
|
||||
const expiresAt = farcasterTimeToDate(event.expiry);
|
||||
|
||||
await this.db
|
||||
.insertInto('fnames')
|
||||
.values({
|
||||
fname: Buffer.from(event.fname).toString('utf8'),
|
||||
custodyAddress,
|
||||
expiresAt,
|
||||
})
|
||||
.onConflict((oc) => oc.columns(['fname']).doUpdateSet({ custodyAddress, expiresAt, updatedAt: new Date() }))
|
||||
.execute();
|
||||
}
|
||||
|
||||
private async onMergeMessage(message: Message) {
|
||||
this.log.debug(`Merging message ${bytesToHex(message.hash)} (type ${message.data?.type})`);
|
||||
|
||||
const isInitialCreation = await this.storeMessage(message, 'merge');
|
||||
|
||||
if (isCastAddMessage(message)) {
|
||||
await this.onCastAdd(message, isInitialCreation);
|
||||
} else if (isCastRemoveMessage(message)) {
|
||||
await this.onCastRemove(message);
|
||||
} else if (isReactionAddMessage(message)) {
|
||||
await this.onReactionAdd(message, isInitialCreation);
|
||||
} else if (isReactionRemoveMessage(message)) {
|
||||
await this.onReactionRemove(message);
|
||||
} else if (isVerificationAddEthAddressMessage(message)) {
|
||||
await this.onVerificationAddEthAddress(message, isInitialCreation);
|
||||
} else if (isVerificationRemoveMessage(message)) {
|
||||
await this.onVerificationRemove(message);
|
||||
} else if (isSignerAddMessage(message)) {
|
||||
await this.onSignerAdd(message, isInitialCreation);
|
||||
} else if (isSignerRemoveMessage(message)) {
|
||||
await this.onSignerRemove(message);
|
||||
} else if (isUserDataAddMessage(message)) {
|
||||
await this.onUserDataAdd(message, isInitialCreation);
|
||||
} else {
|
||||
this.log.warn(`Ignoring unknown message type ${message.data?.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
private async onPruneMessage(message: Message) {
|
||||
this.log.debug(`Pruning message ${bytesToHex(message.hash)} (type ${message.data?.type})`);
|
||||
this.storeMessage(message, 'prune');
|
||||
}
|
||||
|
||||
private async onRevokeMessage(message: Message) {
|
||||
this.log.debug(`Revoking message ${bytesToHex(message.hash)} (type ${message.data?.type})`);
|
||||
this.storeMessage(message, 'revoke');
|
||||
}
|
||||
|
||||
private async onCastAdd(message: CastAddMessage, isInitialCreation: boolean) {
|
||||
await this.db
|
||||
.insertInto('casts')
|
||||
.values({
|
||||
timestamp: farcasterTimeToDate(message.data.timestamp),
|
||||
fid: message.data.fid,
|
||||
text: message.data.castAddBody.text,
|
||||
hash: message.hash,
|
||||
parentHash: message.data.castAddBody.parentCastId?.hash,
|
||||
parentFid: message.data.castAddBody.parentCastId?.fid,
|
||||
parentUrl: message.data.castAddBody.parentUrl,
|
||||
embeds: message.data.castAddBody.embedsDeprecated,
|
||||
mentions: message.data.castAddBody.mentions,
|
||||
mentionsPositions: message.data.castAddBody.mentionsPositions,
|
||||
})
|
||||
// Do nothing on conflict since nothing should have changed if hash is the same.
|
||||
.onConflict((oc) => oc.columns(['hash']).doNothing())
|
||||
.execute();
|
||||
|
||||
if (isInitialCreation) {
|
||||
// TODO: Execute any one-time side effects, e.g. sending push
|
||||
// notifications to user whose cast was replied to, etc.
|
||||
}
|
||||
}
|
||||
|
||||
private async onCastRemove(message: CastRemoveMessage) {
|
||||
await this.db
|
||||
.updateTable('casts')
|
||||
.where('fid', '=', message.data.fid)
|
||||
.where('hash', '=', message.data.castRemoveBody.targetHash)
|
||||
.set({ deletedAt: farcasterTimeToDate(message.data.timestamp) })
|
||||
.execute();
|
||||
|
||||
// TODO: Execute any cleanup side effects to remove the cast
|
||||
}
|
||||
|
||||
private async onReactionAdd(message: ReactionAddMessage, isInitialCreation: boolean) {
|
||||
await this.db
|
||||
.insertInto('reactions')
|
||||
.values({
|
||||
fid: message.data.fid,
|
||||
timestamp: farcasterTimeToDate(message.data.timestamp),
|
||||
hash: message.hash,
|
||||
reactionType: message.data.reactionBody.type,
|
||||
targetHash: message.data.reactionBody.targetCastId?.hash,
|
||||
targetFid: message.data.reactionBody.targetCastId?.fid,
|
||||
targetUrl: message.data.reactionBody.targetUrl,
|
||||
})
|
||||
// Do nothing on conflict since nothing should have changed if hash is the same.
|
||||
.onConflict((oc) => oc.columns(['hash']).doNothing())
|
||||
.execute();
|
||||
|
||||
if (isInitialCreation) {
|
||||
// TODO: Execute any one-time side effects, e.g. sending push
|
||||
// notifications to user whose cast was liked, etc.
|
||||
}
|
||||
}
|
||||
|
||||
private async onReactionRemove(message: ReactionRemoveMessage) {
|
||||
await this.db
|
||||
.updateTable('reactions')
|
||||
.where('fid', '=', message.data.fid)
|
||||
.where((eb) => {
|
||||
// Search based on the type of reaction
|
||||
if (message.data.reactionBody.targetUrl) {
|
||||
return eb.where('targetUrl', '=', message.data.reactionBody.targetUrl);
|
||||
} else if (message.data.reactionBody.targetCastId) {
|
||||
return eb
|
||||
.where('targetFid', '=', message.data.reactionBody.targetCastId.fid)
|
||||
.where('targetHash', '=', message.data.reactionBody.targetCastId.hash);
|
||||
} else {
|
||||
throw new Error('Reaction had neither targetUrl nor targetCastId');
|
||||
}
|
||||
})
|
||||
.set({ deletedAt: farcasterTimeToDate(message.data.timestamp) })
|
||||
.execute();
|
||||
|
||||
// TODO: Execute any cleanup side effects to remove the cast
|
||||
}
|
||||
|
||||
private async onVerificationAddEthAddress(message: VerificationAddEthAddressMessage, isInitialCreation: boolean) {
|
||||
await this.db
|
||||
.insertInto('verifications')
|
||||
.values({
|
||||
fid: message.data.fid,
|
||||
timestamp: farcasterTimeToDate(message.data.timestamp),
|
||||
hash: message.hash,
|
||||
claim: {
|
||||
address: bytesToHex(message.data.verificationAddEthAddressBody.address),
|
||||
ethSignature: bytesToHex(message.data.verificationAddEthAddressBody.ethSignature),
|
||||
blockHash: bytesToHex(message.data.verificationAddEthAddressBody.blockHash),
|
||||
},
|
||||
})
|
||||
// Do nothing on conflict since nothing should have changed if hash is the same.
|
||||
.onConflict((oc) => oc.columns(['hash']).doNothing())
|
||||
.execute();
|
||||
|
||||
if (isInitialCreation) {
|
||||
// TODO: Execute any one-time side effects
|
||||
}
|
||||
|
||||
// TODO: Execute any side effects that should happen any time the user
|
||||
// connects the wallet (even if they are reconnecting a previously
|
||||
// disconnected wallet), e.g. fetching token balances and NFTs for their
|
||||
// wallet address.
|
||||
}
|
||||
|
||||
private async onVerificationRemove(message: VerificationRemoveMessage) {
|
||||
await this.db
|
||||
.updateTable('verifications')
|
||||
.where('fid', '=', message.data.fid)
|
||||
.where(sql`claim ->> 'address'`, '=', bytesToHex(message.data.verificationRemoveBody.address))
|
||||
.set({ deletedAt: farcasterTimeToDate(message.data.timestamp) })
|
||||
.execute();
|
||||
|
||||
// TODO: Execute any cleanup side effects, e.g. updating NFT ownership
|
||||
}
|
||||
|
||||
private async onSignerAdd(message: SignerAddMessage, isInitialCreation: boolean) {
|
||||
const signerName = message.data.signerAddBody.name;
|
||||
|
||||
await this.db
|
||||
.insertInto('signers')
|
||||
.values({
|
||||
fid: message.data.fid,
|
||||
timestamp: farcasterTimeToDate(message.data.timestamp),
|
||||
hash: message.hash,
|
||||
custodyAddress: message.signer,
|
||||
signer: message.data.signerAddBody.signer,
|
||||
name: signerName?.length ? signerName : null, // Treat empty string signer names as not specified
|
||||
})
|
||||
// Do nothing on conflict since nothing should have changed if hash is the same.
|
||||
.onConflict((oc) => oc.columns(['hash']).doNothing())
|
||||
.execute();
|
||||
|
||||
if (isInitialCreation) {
|
||||
// TODO: Execute any one-time side effects
|
||||
}
|
||||
}
|
||||
|
||||
private async onSignerRemove(message: SignerRemoveMessage) {
|
||||
await this.db
|
||||
.updateTable('signers')
|
||||
.where('fid', '=', message.data.fid)
|
||||
.where('signer', '=', message.data.signerRemoveBody.signer)
|
||||
.set({ deletedAt: farcasterTimeToDate(message.data.timestamp) })
|
||||
.execute();
|
||||
|
||||
// TODO: Execute any cleanup side effects
|
||||
}
|
||||
|
||||
private async onUserDataAdd(message: UserDataAddMessage, isInitialCreation: boolean) {
|
||||
await this.db
|
||||
.insertInto('userData')
|
||||
.values({
|
||||
timestamp: farcasterTimeToDate(message.data.timestamp),
|
||||
fid: message.data.fid,
|
||||
hash: message.hash,
|
||||
type: message.data.userDataBody.type,
|
||||
value: message.data.userDataBody.value,
|
||||
})
|
||||
.onConflict((oc) =>
|
||||
oc
|
||||
.columns(['hash'])
|
||||
.doUpdateSet({
|
||||
timestamp: farcasterTimeToDate(message.data.timestamp),
|
||||
value: message.data.userDataBody.value,
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(({ or, cmpr, ref }) =>
|
||||
// Only update if a value has actually changed
|
||||
or([
|
||||
cmpr('excluded.timestamp', '!=', ref('userData.timestamp')),
|
||||
cmpr('excluded.value', '!=', ref('userData.value')),
|
||||
cmpr('excluded.updatedAt', '!=', ref('userData.updatedAt')),
|
||||
])
|
||||
)
|
||||
)
|
||||
.execute();
|
||||
|
||||
if (isInitialCreation) {
|
||||
// TODO: Execute any one-time side effects
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
import { ClientReadableStream, HubEvent, HubEventType, HubRpcClient } from '@farcaster/hub-nodejs';
|
||||
import { Result, ok, err } from 'neverthrow';
|
||||
import { Logger } from 'pino';
|
||||
import { TypedEmitter } from 'tiny-typed-emitter';
|
||||
|
||||
interface HubEvents {
|
||||
event: (hubEvent: HubEvent) => void;
|
||||
}
|
||||
|
||||
export class HubSubscriber extends TypedEmitter<HubEvents> {
|
||||
public hubClient: HubRpcClient;
|
||||
public stopped = true;
|
||||
private log: Logger;
|
||||
|
||||
private stream: ClientReadableStream<HubEvent> | null = null;
|
||||
|
||||
constructor(hubClient: HubRpcClient, log: Logger) {
|
||||
super();
|
||||
this.hubClient = hubClient;
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public stop() {
|
||||
this.stream?.cancel();
|
||||
this.stopped = true;
|
||||
this.log.info(`Stopped HubSubscriber`);
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
if (!this.stopped) this.stop();
|
||||
this.hubClient.$.close();
|
||||
}
|
||||
|
||||
private _waitForReadyHubClient(): Promise<Result<void, unknown>> {
|
||||
return new Promise((resolve) => {
|
||||
this.hubClient?.$.waitForReady(Date.now() + 500, (e) => {
|
||||
return e ? resolve(err(e)) : resolve(ok(undefined));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public async start(fromId?: number) {
|
||||
this.log.info(`Starting HubSubscriber`);
|
||||
|
||||
const hubClientReady = await this._waitForReadyHubClient();
|
||||
if (hubClientReady.isErr()) {
|
||||
this.log.error(`Failed to connect to hub: ${hubClientReady.error}`);
|
||||
return err(hubClientReady.error);
|
||||
}
|
||||
this.log.info(`Connected to hub`);
|
||||
|
||||
const subscribeParams: { eventTypes: HubEventType[]; fromId?: number } = {
|
||||
eventTypes: [
|
||||
HubEventType.MERGE_MESSAGE,
|
||||
HubEventType.REVOKE_MESSAGE,
|
||||
HubEventType.PRUNE_MESSAGE,
|
||||
HubEventType.MERGE_ID_REGISTRY_EVENT,
|
||||
HubEventType.MERGE_NAME_REGISTRY_EVENT,
|
||||
],
|
||||
fromId,
|
||||
};
|
||||
|
||||
const subscribeRequest = await this.hubClient.subscribe(subscribeParams);
|
||||
return subscribeRequest
|
||||
.andThen((stream) => {
|
||||
this.log.info(`Subscribed to hub events`);
|
||||
this.stream = stream;
|
||||
this.stopped = false;
|
||||
|
||||
stream.on('close', async () => {
|
||||
this.log.info(`HubSubscriber stream closed`);
|
||||
this.stopped = true;
|
||||
this.stream = null;
|
||||
});
|
||||
|
||||
void this.processStream(stream);
|
||||
|
||||
return ok(stream);
|
||||
})
|
||||
.orElse((e) => {
|
||||
this.log.error(`Error starting hub stream: ${e}`);
|
||||
return err(e);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the stream in paused mode so hub events are processed serially and in order.
|
||||
*/
|
||||
private async processStream(stream: ClientReadableStream<HubEvent>) {
|
||||
this.log.debug(`Started hub event stream processing`);
|
||||
try {
|
||||
for await (const event of stream) {
|
||||
const fnLog = this.log.child({ eventId: event.id, eventType: event.type });
|
||||
fnLog.debug(`Processing event ${event.id} (${event.type})`);
|
||||
this.emit('event', event);
|
||||
}
|
||||
} catch (e: any) {
|
||||
this.log.info(`Hub event stream processing halted ${e.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import { HubReplicator } from './hubReplicator';
|
||||
import { getDbClient, migrateToLatest } from './db';
|
||||
import { log } from './log';
|
||||
|
||||
/**
|
||||
* Populate the following constants with your own values.
|
||||
*
|
||||
* If you're running this from the examples directory, make sure you follow the
|
||||
* README.
|
||||
*/
|
||||
const HUB_URL = 'nemes.farcaster.xyz:2283'; // URL of the Hub
|
||||
const HUB_SSL = true; // Change if your hub isn't using SSL/TLS
|
||||
const POSTGRES_URL = 'postgres://app:password@localhost:6543/hub';
|
||||
|
||||
const db = getDbClient(POSTGRES_URL);
|
||||
|
||||
let replicator: HubReplicator | undefined;
|
||||
|
||||
const shutdown = async () => {
|
||||
if (replicator) {
|
||||
await replicator.stop();
|
||||
await replicator.destroy();
|
||||
}
|
||||
|
||||
if (db) {
|
||||
await db.destroy();
|
||||
}
|
||||
};
|
||||
|
||||
process.on('exit', (code) => {
|
||||
log.info(`Exiting process with status code ${code}`);
|
||||
});
|
||||
|
||||
for (const signal of ['SIGTERM', 'SIGINT']) {
|
||||
process.once(signal, (signalName: string) => {
|
||||
log.info(`Process received ${signalName}`);
|
||||
process.exitCode =
|
||||
// eslint-disable-next-line security/detect-object-injection
|
||||
{
|
||||
SIGINT: 130,
|
||||
SIGTERM: 143,
|
||||
}[signalName] || 1;
|
||||
|
||||
shutdown();
|
||||
});
|
||||
}
|
||||
|
||||
(async () => {
|
||||
// Create DB tables
|
||||
const result = await migrateToLatest(db, log);
|
||||
if (result.isErr()) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
replicator = new HubReplicator(HUB_URL, HUB_SSL, db, log);
|
||||
replicator.start();
|
||||
})();
|
||||
@@ -0,0 +1,5 @@
|
||||
import { pino } from 'pino';
|
||||
|
||||
export const log = pino();
|
||||
|
||||
export type Logger = pino.Logger;
|
||||
@@ -0,0 +1,187 @@
|
||||
import { Kysely, sql } from 'kysely';
|
||||
|
||||
export const up = async (db: Kysely<any>) => {
|
||||
await db.schema
|
||||
.createTable('hubSubscriptions')
|
||||
.addColumn('host', 'text', (col) => col.notNull().primaryKey())
|
||||
.addColumn('last_event_id', 'bigint')
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createTable('messages')
|
||||
.addColumn('id', 'bigint', (col) => col.generatedAlwaysAsIdentity().primaryKey())
|
||||
.addColumn('createdAt', 'timestamp', (col) => col.notNull().defaultTo(sql`current_timestamp`))
|
||||
.addColumn('updatedAt', 'timestamp', (col) => col.notNull().defaultTo(sql`current_timestamp`))
|
||||
.addColumn('deletedAt', 'timestamp')
|
||||
.addColumn('prunedAt', 'timestamp')
|
||||
.addColumn('revokedAt', 'timestamp')
|
||||
.addColumn('timestamp', 'timestamp', (col) => col.notNull())
|
||||
.addColumn('messageType', sql`smallint`, (col) => col.notNull())
|
||||
.addColumn('fid', 'bigint', (col) => col.notNull())
|
||||
.addColumn('hash', sql`bytea`, (col) => col.notNull())
|
||||
.addColumn('hashScheme', sql`smallint`, (col) => col.notNull())
|
||||
.addColumn('signature', sql`bytea`, (col) => col.notNull())
|
||||
.addColumn('signatureScheme', sql`smallint`, (col) => col.notNull())
|
||||
.addColumn('signer', sql`bytea`, (col) => col.notNull())
|
||||
.addColumn('raw', sql`bytea`, (col) => col.notNull())
|
||||
.addUniqueConstraint('messages_hash_unique', ['hash'])
|
||||
.execute();
|
||||
|
||||
await db.schema.createIndex('messages_timestamp_index').on('messages').columns(['timestamp']).execute();
|
||||
|
||||
await db.schema
|
||||
.createTable('casts')
|
||||
.addColumn('id', 'bigint', (col) => col.generatedAlwaysAsIdentity().primaryKey())
|
||||
.addColumn('createdAt', 'timestamp', (col) => col.notNull().defaultTo(sql`current_timestamp`))
|
||||
.addColumn('updatedAt', 'timestamp', (col) => col.notNull().defaultTo(sql`current_timestamp`))
|
||||
.addColumn('deletedAt', 'timestamp')
|
||||
.addColumn('timestamp', 'timestamp', (col) => col.notNull())
|
||||
.addColumn('fid', 'bigint', (col) => col.notNull())
|
||||
.addColumn('hash', sql`bytea`, (col) => col.notNull())
|
||||
.addColumn('parentHash', sql`bytea`)
|
||||
.addColumn('parentFid', 'bigint')
|
||||
.addColumn('parentUrl', 'text')
|
||||
.addColumn('text', 'text', (col) => col.notNull())
|
||||
.addColumn('embeds', sql`text[]`, (col) => col.notNull().defaultTo(sql`'{}'`))
|
||||
.addColumn('mentions', sql`bigint[]`, (col) => col.notNull().defaultTo(sql`'{}'`))
|
||||
.addColumn('mentionsPositions', sql`smallint[]`, (col) => col.notNull().defaultTo(sql`'{}'`))
|
||||
.addUniqueConstraint('casts_hash_unique', ['hash'])
|
||||
.addForeignKeyConstraint('casts_hash_foreign', ['hash'], 'messages', ['hash'])
|
||||
.execute();
|
||||
|
||||
await db.schema.createIndex('casts_fid_timestamp_index').on('casts').columns(['fid', 'timestamp']).execute();
|
||||
await db.schema.createIndex('casts_timestamp_index').on('casts').columns(['timestamp']).execute();
|
||||
await db.schema
|
||||
.createIndex('casts_parent_hash_parent_fid_index')
|
||||
.on('casts')
|
||||
.columns(['parentHash', 'parentFid'])
|
||||
.where('parentHash', 'is not', null)
|
||||
.where('parentFid', 'is not', null)
|
||||
.execute();
|
||||
await db.schema
|
||||
.createIndex('casts_parent_url_index')
|
||||
.on('casts')
|
||||
.columns(['parentUrl'])
|
||||
.where('parentUrl', 'is not', null)
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createTable('reactions')
|
||||
.addColumn('id', 'bigint', (col) => col.generatedAlwaysAsIdentity().primaryKey())
|
||||
.addColumn('createdAt', 'timestamp', (col) => col.notNull().defaultTo(sql`current_timestamp`))
|
||||
.addColumn('updatedAt', 'timestamp', (col) => col.notNull().defaultTo(sql`current_timestamp`))
|
||||
.addColumn('deletedAt', 'timestamp')
|
||||
.addColumn('timestamp', 'timestamp', (col) => col.notNull())
|
||||
.addColumn('reactionType', sql`smallint`, (col) => col.notNull())
|
||||
.addColumn('fid', 'bigint', (col) => col.notNull())
|
||||
.addColumn('hash', sql`bytea`, (col) => col.notNull())
|
||||
.addColumn('targetHash', sql`bytea`)
|
||||
.addColumn('targetFid', 'bigint')
|
||||
.addColumn('targetUrl', 'text')
|
||||
.addUniqueConstraint('reactions_hash_unique', ['hash'])
|
||||
.addForeignKeyConstraint('reactions_hash_foreign', ['hash'], 'messages', ['hash'])
|
||||
.execute();
|
||||
|
||||
await db.schema.createIndex('reactions_fid_timestamp_index').on('reactions').columns(['fid', 'timestamp']).execute();
|
||||
await db.schema
|
||||
.createIndex('reactions_target_hash_target_fid_index')
|
||||
.on('reactions')
|
||||
.columns(['targetHash', 'targetFid'])
|
||||
.where('targetHash', 'is not', null)
|
||||
.where('targetFid', 'is not', null)
|
||||
.execute();
|
||||
await db.schema
|
||||
.createIndex('reactions_target_url_index')
|
||||
.on('reactions')
|
||||
.columns(['targetUrl'])
|
||||
.where('targetUrl', 'is not', null)
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createTable('signers')
|
||||
.addColumn('id', 'bigint', (col) => col.generatedAlwaysAsIdentity().primaryKey())
|
||||
.addColumn('createdAt', 'timestamp', (col) => col.notNull().defaultTo(sql`current_timestamp`))
|
||||
.addColumn('updatedAt', 'timestamp', (col) => col.notNull().defaultTo(sql`current_timestamp`))
|
||||
.addColumn('deletedAt', 'timestamp')
|
||||
.addColumn('timestamp', 'timestamp', (col) => col.notNull())
|
||||
.addColumn('fid', 'bigint', (col) => col.notNull())
|
||||
.addColumn('hash', sql`bytea`, (col) => col.notNull())
|
||||
.addColumn('custodyAddress', sql`bytea`, (col) => col.notNull())
|
||||
.addColumn('signer', sql`bytea`, (col) => col.notNull())
|
||||
.addColumn('name', 'text')
|
||||
.addUniqueConstraint('signers_hash_unique', ['hash'])
|
||||
.addForeignKeyConstraint('signers_hash_foreign', ['hash'], 'messages', ['hash'])
|
||||
.execute();
|
||||
|
||||
await db.schema.createIndex('signers_fid_timestamp_index').on('signers').columns(['fid', 'timestamp']).execute();
|
||||
|
||||
await db.schema
|
||||
.createTable('verifications')
|
||||
.addColumn('id', 'bigint', (col) => col.generatedAlwaysAsIdentity().primaryKey())
|
||||
.addColumn('createdAt', 'timestamp', (col) => col.notNull().defaultTo(sql`current_timestamp`))
|
||||
.addColumn('updatedAt', 'timestamp', (col) => col.notNull().defaultTo(sql`current_timestamp`))
|
||||
.addColumn('deletedAt', 'timestamp')
|
||||
.addColumn('timestamp', 'timestamp', (col) => col.notNull())
|
||||
.addColumn('fid', 'bigint', (col) => col.notNull())
|
||||
.addColumn('hash', sql`bytea`, (col) => col.notNull())
|
||||
.addColumn('claim', 'jsonb', (col) => col.notNull())
|
||||
.addUniqueConstraint('verifications_hash_unique', ['hash'])
|
||||
.addForeignKeyConstraint('verifications_ash_foreign', ['hash'], 'messages', ['hash'])
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createIndex('verifications_claim_address_index')
|
||||
.on('verifications')
|
||||
.expression(sql`(claim ->> 'address'::text)`)
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createIndex('verifications_fid_timestamp_index')
|
||||
.on('verifications')
|
||||
.columns(['fid', 'timestamp'])
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createTable('userData')
|
||||
.addColumn('id', 'bigint', (col) => col.generatedAlwaysAsIdentity().primaryKey())
|
||||
.addColumn('createdAt', 'timestamp', (col) => col.notNull().defaultTo(sql`current_timestamp`))
|
||||
.addColumn('updatedAt', 'timestamp', (col) => col.notNull().defaultTo(sql`current_timestamp`))
|
||||
.addColumn('deletedAt', 'timestamp')
|
||||
.addColumn('timestamp', 'timestamp', (col) => col.notNull())
|
||||
.addColumn('fid', 'bigint', (col) => col.notNull())
|
||||
.addColumn('hash', sql`bytea`, (col) => col.notNull())
|
||||
.addColumn('type', sql`smallint`, (col) => col.notNull())
|
||||
.addColumn('value', 'text', (col) => col.notNull())
|
||||
.addUniqueConstraint('user_data_hash_unique', ['hash'])
|
||||
.addUniqueConstraint('user_data_fid_type_unique', ['fid', 'type'])
|
||||
.addForeignKeyConstraint('user_data_hash_foreign', ['hash'], 'messages', ['hash'])
|
||||
.execute();
|
||||
|
||||
await db.schema.createIndex('user_data_fid_index').on('user_data').columns(['fid']).execute();
|
||||
|
||||
await db.schema
|
||||
.createTable('fids')
|
||||
.addColumn('fid', 'bigint', (col) => col.primaryKey())
|
||||
.addColumn('createdAt', 'timestamp', (col) => col.notNull().defaultTo(sql`current_timestamp`))
|
||||
.addColumn('updatedAt', 'timestamp', (col) => col.notNull().defaultTo(sql`current_timestamp`))
|
||||
.addColumn('custodyAddress', sql`bytea`, (col) => col.notNull())
|
||||
.execute();
|
||||
|
||||
await db.schema
|
||||
.createTable('fnames')
|
||||
.addColumn('fname', 'text', (col) => col.primaryKey())
|
||||
.addColumn('createdAt', 'timestamp', (col) => col.notNull().defaultTo(sql`current_timestamp`))
|
||||
.addColumn('updatedAt', 'timestamp', (col) => col.notNull().defaultTo(sql`current_timestamp`))
|
||||
.addColumn('custodyAddress', sql`bytea`, (col) => col.notNull())
|
||||
.addColumn('expiresAt', 'timestamp', (col) => col.notNull())
|
||||
.execute();
|
||||
};
|
||||
|
||||
export const down = async (db: Kysely<any>) => {
|
||||
await db.schema.dropTable('casts').ifExists().execute();
|
||||
await db.schema.dropTable('reactions').ifExists().execute();
|
||||
await db.schema.dropTable('signers').ifExists().execute();
|
||||
await db.schema.dropTable('verifications').ifExists().execute();
|
||||
await db.schema.dropTable('userData').ifExists().execute();
|
||||
await db.schema.dropTable('messages').ifExists().execute();
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "example-replicate-data-postgres",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"version": "0.0.0",
|
||||
"main": "index.ts",
|
||||
"scripts": {
|
||||
"start": "tsx index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@farcaster/hub-nodejs": "^0.7.1",
|
||||
"kysely": "^0.24.2",
|
||||
"kysely-postgres-js": "^1.1.1",
|
||||
"pino": "^8.12.1",
|
||||
"postgres": "^3.3.4",
|
||||
"tiny-typed-emitter": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tsx": "^3.12.5",
|
||||
"typescript": "^5.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"moduleResolution": "Node",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noImplicitReturns": true,
|
||||
}
|
||||
}
|
||||
24
packages/hub-nodejs/examples/replicate-data-postgres/util.ts
Normal file
24
packages/hub-nodejs/examples/replicate-data-postgres/util.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
/* eslint-disable prefer-arrow-functions/prefer-arrow-functions */
|
||||
|
||||
import { fromFarcasterTime } from '@farcaster/hub-nodejs';
|
||||
|
||||
export function farcasterTimeToDate(time: undefined): undefined;
|
||||
export function farcasterTimeToDate(time: null): null;
|
||||
export function farcasterTimeToDate(time: number): Date;
|
||||
export function farcasterTimeToDate(time: number | null | undefined): Date | null | undefined;
|
||||
export function farcasterTimeToDate(time: number | null | undefined): Date | null | undefined {
|
||||
if (time === undefined) return undefined;
|
||||
if (time === null) return null;
|
||||
const result = fromFarcasterTime(time);
|
||||
if (result.isErr()) throw result.error;
|
||||
return new Date(result.value);
|
||||
}
|
||||
|
||||
export function bytesToHex(bytes: undefined): undefined;
|
||||
export function bytesToHex(bytes: null): null;
|
||||
export function bytesToHex(bytes: Uint8Array): string;
|
||||
export function bytesToHex(bytes: Uint8Array | null | undefined): string | null | undefined {
|
||||
if (bytes === undefined) return undefined;
|
||||
if (bytes === null) return null;
|
||||
return '0x' + Buffer.from(bytes).toString('hex');
|
||||
}
|
||||
953
packages/hub-nodejs/examples/replicate-data-postgres/yarn.lock
Normal file
953
packages/hub-nodejs/examples/replicate-data-postgres/yarn.lock
Normal file
@@ -0,0 +1,953 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@adraffy/ens-normalize@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.9.0.tgz#223572538f6bea336750039bb43a4016dcc8182d"
|
||||
integrity sha512-iowxq3U30sghZotgl4s/oJRci6WPBfNO5YYgk2cIOMCHr3LeGPcsZjCEr+33Q4N+oV3OABDAtA+pyvWjbvBifQ==
|
||||
|
||||
"@esbuild-kit/cjs-loader@^2.4.2":
|
||||
version "2.4.2"
|
||||
resolved "https://registry.npmjs.org/@esbuild-kit/cjs-loader/-/cjs-loader-2.4.2.tgz#cb4dde00fbf744a68c4f20162ea15a8242d0fa54"
|
||||
integrity sha512-BDXFbYOJzT/NBEtp71cvsrGPwGAMGRB/349rwKuoxNSiKjPraNNnlK6MIIabViCjqZugu6j+xeMDlEkWdHHJSg==
|
||||
dependencies:
|
||||
"@esbuild-kit/core-utils" "^3.0.0"
|
||||
get-tsconfig "^4.4.0"
|
||||
|
||||
"@esbuild-kit/core-utils@^3.0.0":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.1.0.tgz#49945d533dbd5e1b7620aa0fc522c15e6ec089c5"
|
||||
integrity sha512-Uuk8RpCg/7fdHSceR1M6XbSZFSuMrxcePFuGgyvsBn+u339dk5OeL4jv2EojwTN2st/unJGsVm4qHWjWNmJ/tw==
|
||||
dependencies:
|
||||
esbuild "~0.17.6"
|
||||
source-map-support "^0.5.21"
|
||||
|
||||
"@esbuild-kit/esm-loader@^2.5.5":
|
||||
version "2.5.5"
|
||||
resolved "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.5.5.tgz#b82da14fcee3fc1d219869756c06f43f67d1ca71"
|
||||
integrity sha512-Qwfvj/qoPbClxCRNuac1Du01r9gvNOT+pMYtJDapfB1eoGN1YlJ1BixLyL9WVENRx5RXgNLdfYdx/CuswlGhMw==
|
||||
dependencies:
|
||||
"@esbuild-kit/core-utils" "^3.0.0"
|
||||
get-tsconfig "^4.4.0"
|
||||
|
||||
"@esbuild/android-arm64@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.18.tgz#4aa8d8afcffb4458736ca9b32baa97d7cb5861ea"
|
||||
integrity sha512-/iq0aK0eeHgSC3z55ucMAHO05OIqmQehiGay8eP5l/5l+iEr4EIbh4/MI8xD9qRFjqzgkc0JkX0LculNC9mXBw==
|
||||
|
||||
"@esbuild/android-arm@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.18.tgz#74a7e95af4ee212ebc9db9baa87c06a594f2a427"
|
||||
integrity sha512-EmwL+vUBZJ7mhFCs5lA4ZimpUH3WMAoqvOIYhVQwdIgSpHC8ImHdsRyhHAVxpDYUSm0lWvd63z0XH1IlImS2Qw==
|
||||
|
||||
"@esbuild/android-x64@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.18.tgz#1dcd13f201997c9fe0b204189d3a0da4eb4eb9b6"
|
||||
integrity sha512-x+0efYNBF3NPW2Xc5bFOSFW7tTXdAcpfEg2nXmxegm4mJuVeS+i109m/7HMiOQ6M12aVGGFlqJX3RhNdYM2lWg==
|
||||
|
||||
"@esbuild/darwin-arm64@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.18.tgz#444f3b961d4da7a89eb9bd35cfa4415141537c2a"
|
||||
integrity sha512-6tY+djEAdF48M1ONWnQb1C+6LiXrKjmqjzPNPWXhu/GzOHTHX2nh8Mo2ZAmBFg0kIodHhciEgUBtcYCAIjGbjQ==
|
||||
|
||||
"@esbuild/darwin-x64@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.18.tgz#a6da308d0ac8a498c54d62e0b2bfb7119b22d315"
|
||||
integrity sha512-Qq84ykvLvya3dO49wVC9FFCNUfSrQJLbxhoQk/TE1r6MjHo3sFF2tlJCwMjhkBVq3/ahUisj7+EpRSz0/+8+9A==
|
||||
|
||||
"@esbuild/freebsd-arm64@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.18.tgz#b83122bb468889399d0d63475d5aea8d6829c2c2"
|
||||
integrity sha512-fw/ZfxfAzuHfaQeMDhbzxp9mc+mHn1Y94VDHFHjGvt2Uxl10mT4CDavHm+/L9KG441t1QdABqkVYwakMUeyLRA==
|
||||
|
||||
"@esbuild/freebsd-x64@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.18.tgz#af59e0e03fcf7f221b34d4c5ab14094862c9c864"
|
||||
integrity sha512-FQFbRtTaEi8ZBi/A6kxOC0V0E9B/97vPdYjY9NdawyLd4Qk5VD5g2pbWN2VR1c0xhzcJm74HWpObPszWC+qTew==
|
||||
|
||||
"@esbuild/linux-arm64@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.18.tgz#8551d72ba540c5bce4bab274a81c14ed01eafdcf"
|
||||
integrity sha512-R7pZvQZFOY2sxUG8P6A21eq6q+eBv7JPQYIybHVf1XkQYC+lT7nDBdC7wWKTrbvMXKRaGudp/dzZCwL/863mZQ==
|
||||
|
||||
"@esbuild/linux-arm@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.18.tgz#e09e76e526df4f665d4d2720d28ff87d15cdf639"
|
||||
integrity sha512-jW+UCM40LzHcouIaqv3e/oRs0JM76JfhHjCavPxMUti7VAPh8CaGSlS7cmyrdpzSk7A+8f0hiedHqr/LMnfijg==
|
||||
|
||||
"@esbuild/linux-ia32@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.18.tgz#47878860ce4fe73a36fd8627f5647bcbbef38ba4"
|
||||
integrity sha512-ygIMc3I7wxgXIxk6j3V00VlABIjq260i967Cp9BNAk5pOOpIXmd1RFQJQX9Io7KRsthDrQYrtcx7QCof4o3ZoQ==
|
||||
|
||||
"@esbuild/linux-loong64@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.18.tgz#3f8fbf5267556fc387d20b2e708ce115de5c967a"
|
||||
integrity sha512-bvPG+MyFs5ZlwYclCG1D744oHk1Pv7j8psF5TfYx7otCVmcJsEXgFEhQkbhNW8otDHL1a2KDINW20cfCgnzgMQ==
|
||||
|
||||
"@esbuild/linux-mips64el@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.18.tgz#9d896d8f3c75f6c226cbeb840127462e37738226"
|
||||
integrity sha512-oVqckATOAGuiUOa6wr8TXaVPSa+6IwVJrGidmNZS1cZVx0HqkTMkqFGD2HIx9H1RvOwFeWYdaYbdY6B89KUMxA==
|
||||
|
||||
"@esbuild/linux-ppc64@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.18.tgz#3d9deb60b2d32c9985bdc3e3be090d30b7472783"
|
||||
integrity sha512-3dLlQO+b/LnQNxgH4l9rqa2/IwRJVN9u/bK63FhOPB4xqiRqlQAU0qDU3JJuf0BmaH0yytTBdoSBHrb2jqc5qQ==
|
||||
|
||||
"@esbuild/linux-riscv64@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.18.tgz#8a943cf13fd24ff7ed58aefb940ef178f93386bc"
|
||||
integrity sha512-/x7leOyDPjZV3TcsdfrSI107zItVnsX1q2nho7hbbQoKnmoeUWjs+08rKKt4AUXju7+3aRZSsKrJtaRmsdL1xA==
|
||||
|
||||
"@esbuild/linux-s390x@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.18.tgz#66cb01f4a06423e5496facabdce4f7cae7cb80e5"
|
||||
integrity sha512-cX0I8Q9xQkL/6F5zWdYmVf5JSQt+ZfZD2bJudZrWD+4mnUvoZ3TDDXtDX2mUaq6upMFv9FlfIh4Gfun0tbGzuw==
|
||||
|
||||
"@esbuild/linux-x64@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.18.tgz#23c26050c6c5d1359c7b774823adc32b3883b6c9"
|
||||
integrity sha512-66RmRsPlYy4jFl0vG80GcNRdirx4nVWAzJmXkevgphP1qf4dsLQCpSKGM3DUQCojwU1hnepI63gNZdrr02wHUA==
|
||||
|
||||
"@esbuild/netbsd-x64@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.18.tgz#789a203d3115a52633ff6504f8cbf757f15e703b"
|
||||
integrity sha512-95IRY7mI2yrkLlTLb1gpDxdC5WLC5mZDi+kA9dmM5XAGxCME0F8i4bYH4jZreaJ6lIZ0B8hTrweqG1fUyW7jbg==
|
||||
|
||||
"@esbuild/openbsd-x64@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.18.tgz#d7b998a30878f8da40617a10af423f56f12a5e90"
|
||||
integrity sha512-WevVOgcng+8hSZ4Q3BKL3n1xTv5H6Nb53cBrtzzEjDbbnOmucEVcZeGCsCOi9bAOcDYEeBZbD2SJNBxlfP3qiA==
|
||||
|
||||
"@esbuild/sunos-x64@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.18.tgz#ecad0736aa7dae07901ba273db9ef3d3e93df31f"
|
||||
integrity sha512-Rzf4QfQagnwhQXVBS3BYUlxmEbcV7MY+BH5vfDZekU5eYpcffHSyjU8T0xucKVuOcdCsMo+Ur5wmgQJH2GfNrg==
|
||||
|
||||
"@esbuild/win32-arm64@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.18.tgz#58dfc177da30acf956252d7c8ae9e54e424887c4"
|
||||
integrity sha512-Kb3Ko/KKaWhjeAm2YoT/cNZaHaD1Yk/pa3FTsmqo9uFh1D1Rfco7BBLIPdDOozrObj2sahslFuAQGvWbgWldAg==
|
||||
|
||||
"@esbuild/win32-ia32@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.18.tgz#340f6163172b5272b5ae60ec12c312485f69232b"
|
||||
integrity sha512-0/xUMIdkVHwkvxfbd5+lfG7mHOf2FRrxNbPiKWg9C4fFrB8H0guClmaM3BFiRUYrznVoyxTIyC/Ou2B7QQSwmw==
|
||||
|
||||
"@esbuild/win32-x64@0.17.18":
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.18.tgz#3a8e57153905308db357fd02f57c180ee3a0a1fa"
|
||||
integrity sha512-qU25Ma1I3NqTSHJUOKi9sAH1/Mzuvlke0ioMJRthLXKm7JiSKVwFghlGbDLOO2sARECGhja4xYfRAZNPAkooYg==
|
||||
|
||||
"@ethersproject/abstract-provider@^5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef"
|
||||
integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==
|
||||
dependencies:
|
||||
"@ethersproject/bignumber" "^5.7.0"
|
||||
"@ethersproject/bytes" "^5.7.0"
|
||||
"@ethersproject/logger" "^5.7.0"
|
||||
"@ethersproject/networks" "^5.7.0"
|
||||
"@ethersproject/properties" "^5.7.0"
|
||||
"@ethersproject/transactions" "^5.7.0"
|
||||
"@ethersproject/web" "^5.7.0"
|
||||
|
||||
"@ethersproject/abstract-signer@^5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2"
|
||||
integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==
|
||||
dependencies:
|
||||
"@ethersproject/abstract-provider" "^5.7.0"
|
||||
"@ethersproject/bignumber" "^5.7.0"
|
||||
"@ethersproject/bytes" "^5.7.0"
|
||||
"@ethersproject/logger" "^5.7.0"
|
||||
"@ethersproject/properties" "^5.7.0"
|
||||
|
||||
"@ethersproject/address@^5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37"
|
||||
integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==
|
||||
dependencies:
|
||||
"@ethersproject/bignumber" "^5.7.0"
|
||||
"@ethersproject/bytes" "^5.7.0"
|
||||
"@ethersproject/keccak256" "^5.7.0"
|
||||
"@ethersproject/logger" "^5.7.0"
|
||||
"@ethersproject/rlp" "^5.7.0"
|
||||
|
||||
"@ethersproject/base64@^5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c"
|
||||
integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==
|
||||
dependencies:
|
||||
"@ethersproject/bytes" "^5.7.0"
|
||||
|
||||
"@ethersproject/bignumber@^5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2"
|
||||
integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==
|
||||
dependencies:
|
||||
"@ethersproject/bytes" "^5.7.0"
|
||||
"@ethersproject/logger" "^5.7.0"
|
||||
bn.js "^5.2.1"
|
||||
|
||||
"@ethersproject/bytes@^5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d"
|
||||
integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==
|
||||
dependencies:
|
||||
"@ethersproject/logger" "^5.7.0"
|
||||
|
||||
"@ethersproject/constants@^5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e"
|
||||
integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==
|
||||
dependencies:
|
||||
"@ethersproject/bignumber" "^5.7.0"
|
||||
|
||||
"@ethersproject/keccak256@^5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a"
|
||||
integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==
|
||||
dependencies:
|
||||
"@ethersproject/bytes" "^5.7.0"
|
||||
js-sha3 "0.8.0"
|
||||
|
||||
"@ethersproject/logger@^5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892"
|
||||
integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==
|
||||
|
||||
"@ethersproject/networks@^5.7.0":
|
||||
version "5.7.1"
|
||||
resolved "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6"
|
||||
integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==
|
||||
dependencies:
|
||||
"@ethersproject/logger" "^5.7.0"
|
||||
|
||||
"@ethersproject/properties@^5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30"
|
||||
integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==
|
||||
dependencies:
|
||||
"@ethersproject/logger" "^5.7.0"
|
||||
|
||||
"@ethersproject/rlp@^5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304"
|
||||
integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==
|
||||
dependencies:
|
||||
"@ethersproject/bytes" "^5.7.0"
|
||||
"@ethersproject/logger" "^5.7.0"
|
||||
|
||||
"@ethersproject/signing-key@^5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3"
|
||||
integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==
|
||||
dependencies:
|
||||
"@ethersproject/bytes" "^5.7.0"
|
||||
"@ethersproject/logger" "^5.7.0"
|
||||
"@ethersproject/properties" "^5.7.0"
|
||||
bn.js "^5.2.1"
|
||||
elliptic "6.5.4"
|
||||
hash.js "1.1.7"
|
||||
|
||||
"@ethersproject/strings@^5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2"
|
||||
integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==
|
||||
dependencies:
|
||||
"@ethersproject/bytes" "^5.7.0"
|
||||
"@ethersproject/constants" "^5.7.0"
|
||||
"@ethersproject/logger" "^5.7.0"
|
||||
|
||||
"@ethersproject/transactions@^5.7.0":
|
||||
version "5.7.0"
|
||||
resolved "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b"
|
||||
integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==
|
||||
dependencies:
|
||||
"@ethersproject/address" "^5.7.0"
|
||||
"@ethersproject/bignumber" "^5.7.0"
|
||||
"@ethersproject/bytes" "^5.7.0"
|
||||
"@ethersproject/constants" "^5.7.0"
|
||||
"@ethersproject/keccak256" "^5.7.0"
|
||||
"@ethersproject/logger" "^5.7.0"
|
||||
"@ethersproject/properties" "^5.7.0"
|
||||
"@ethersproject/rlp" "^5.7.0"
|
||||
"@ethersproject/signing-key" "^5.7.0"
|
||||
|
||||
"@ethersproject/web@^5.7.0":
|
||||
version "5.7.1"
|
||||
resolved "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae"
|
||||
integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==
|
||||
dependencies:
|
||||
"@ethersproject/base64" "^5.7.0"
|
||||
"@ethersproject/bytes" "^5.7.0"
|
||||
"@ethersproject/logger" "^5.7.0"
|
||||
"@ethersproject/properties" "^5.7.0"
|
||||
"@ethersproject/strings" "^5.7.0"
|
||||
|
||||
"@faker-js/faker@^7.6.0":
|
||||
version "7.6.0"
|
||||
resolved "https://registry.npmjs.org/@faker-js/faker/-/faker-7.6.0.tgz#9ea331766084288634a9247fcd8b84f16ff4ba07"
|
||||
integrity sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==
|
||||
|
||||
"@farcaster/core@0.7.1":
|
||||
version "0.7.1"
|
||||
resolved "https://registry.npmjs.org/@farcaster/core/-/core-0.7.1.tgz#69525a1cf4485dd5e0a24395daf1ae35fd0e38cb"
|
||||
integrity sha512-2hVRWSgMDnoHFsuCzKhaTmsp7XWMk1QSE0RLjHarQYbosz6fILHB8F57fEZ0unAi0vDqgoMabvNLdkqQiO6HCQ==
|
||||
dependencies:
|
||||
"@ethersproject/abstract-signer" "^5.7.0"
|
||||
"@faker-js/faker" "^7.6.0"
|
||||
"@noble/ed25519" "^1.7.3"
|
||||
"@noble/hashes" "^1.3.0"
|
||||
ethers "~6.2.1"
|
||||
neverthrow "^6.0.0"
|
||||
viem "^0.3.2"
|
||||
|
||||
"@farcaster/hub-nodejs@^0.7.1":
|
||||
version "0.7.1"
|
||||
resolved "https://registry.npmjs.org/@farcaster/hub-nodejs/-/hub-nodejs-0.7.1.tgz#5ebe822890ebc4fe48f2ba2d58d5e2a78778ac65"
|
||||
integrity sha512-w9U619g041RAuNlL+QXB52fLygBVBGClhbDP+28LbosDLShCPxxdpMC3Wtr5YiwusinXtiqR46yYTFuQBsEGag==
|
||||
dependencies:
|
||||
"@farcaster/core" "0.7.1"
|
||||
"@grpc/grpc-js" "^1.8.13"
|
||||
"@noble/hashes" "^1.3.0"
|
||||
ethers "~6.2.1"
|
||||
neverthrow "^6.0.0"
|
||||
|
||||
"@grpc/grpc-js@^1.8.13":
|
||||
version "1.8.14"
|
||||
resolved "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.8.14.tgz#4fe0f9917d6f094cf59245763c275442b182e9ad"
|
||||
integrity sha512-w84maJ6CKl5aApCMzFll0hxtFNT6or9WwMslobKaqWUEf1K+zhlL43bSQhFreyYWIWR+Z0xnVFC1KtLm4ZpM/A==
|
||||
dependencies:
|
||||
"@grpc/proto-loader" "^0.7.0"
|
||||
"@types/node" ">=12.12.47"
|
||||
|
||||
"@grpc/proto-loader@^0.7.0":
|
||||
version "0.7.7"
|
||||
resolved "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.7.tgz#d33677a77eea8407f7c66e2abd97589b60eb4b21"
|
||||
integrity sha512-1TIeXOi8TuSCQprPItwoMymZXxWT0CPxUhkrkeCUH+D8U7QDwQ6b7SUz2MaLuWM2llT+J/TVFLmQI5KtML3BhQ==
|
||||
dependencies:
|
||||
"@types/long" "^4.0.1"
|
||||
lodash.camelcase "^4.3.0"
|
||||
long "^4.0.0"
|
||||
protobufjs "^7.0.0"
|
||||
yargs "^17.7.2"
|
||||
|
||||
"@noble/curves@0.9.0":
|
||||
version "0.9.0"
|
||||
resolved "https://registry.npmjs.org/@noble/curves/-/curves-0.9.0.tgz#d59713ecbb6a77381de84fb8969381fa85a7380b"
|
||||
integrity sha512-OAdtHMXBp7Chl2lcTn/i7vnFX/q+hhTwDnek5NfYfZsY4LyaUuHCcoq2JlLY3BTFTLT+ZhYZalhF6ejlV7KnJQ==
|
||||
dependencies:
|
||||
"@noble/hashes" "1.3.0"
|
||||
|
||||
"@noble/curves@~0.8.3":
|
||||
version "0.8.3"
|
||||
resolved "https://registry.npmjs.org/@noble/curves/-/curves-0.8.3.tgz#ad6d48baf2599cf1d58dcb734c14d5225c8996e0"
|
||||
integrity sha512-OqaOf4RWDaCRuBKJLDURrgVxjLmneGsiCXGuzYB5y95YithZMA6w4uk34DHSm0rKMrrYiaeZj48/81EvaAScLQ==
|
||||
dependencies:
|
||||
"@noble/hashes" "1.3.0"
|
||||
|
||||
"@noble/ed25519@^1.7.3":
|
||||
version "1.7.3"
|
||||
resolved "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.3.tgz#57e1677bf6885354b466c38e2b620c62f45a7123"
|
||||
integrity sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==
|
||||
|
||||
"@noble/hashes@1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz#e9e035b9b166ca0af657a7848eb2718f0f22f183"
|
||||
integrity sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==
|
||||
|
||||
"@noble/hashes@1.3.0", "@noble/hashes@^1.3.0", "@noble/hashes@~1.3.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1"
|
||||
integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==
|
||||
|
||||
"@noble/secp256k1@1.7.1":
|
||||
version "1.7.1"
|
||||
resolved "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c"
|
||||
integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==
|
||||
|
||||
"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
|
||||
integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==
|
||||
|
||||
"@protobufjs/base64@^1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735"
|
||||
integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==
|
||||
|
||||
"@protobufjs/codegen@^2.0.4":
|
||||
version "2.0.4"
|
||||
resolved "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb"
|
||||
integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==
|
||||
|
||||
"@protobufjs/eventemitter@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
|
||||
integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==
|
||||
|
||||
"@protobufjs/fetch@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
|
||||
integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==
|
||||
dependencies:
|
||||
"@protobufjs/aspromise" "^1.1.1"
|
||||
"@protobufjs/inquire" "^1.1.0"
|
||||
|
||||
"@protobufjs/float@^1.0.2":
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
|
||||
integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==
|
||||
|
||||
"@protobufjs/inquire@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
|
||||
integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==
|
||||
|
||||
"@protobufjs/path@^1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
|
||||
integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==
|
||||
|
||||
"@protobufjs/pool@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
|
||||
integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==
|
||||
|
||||
"@protobufjs/utf8@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
|
||||
integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
|
||||
|
||||
"@scure/base@~1.1.0":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"
|
||||
integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==
|
||||
|
||||
"@scure/bip32@1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/@scure/bip32/-/bip32-1.2.0.tgz#35692d8f8cc3207200239fc119f9e038e5f465df"
|
||||
integrity sha512-O+vT/hBVk+ag2i6j2CDemwd1E1MtGt+7O1KzrPNsaNvSsiEK55MyPIxJIMI2PS8Ijj464B2VbQlpRoQXxw1uHg==
|
||||
dependencies:
|
||||
"@noble/curves" "~0.8.3"
|
||||
"@noble/hashes" "~1.3.0"
|
||||
"@scure/base" "~1.1.0"
|
||||
|
||||
"@scure/bip39@1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.0.tgz#a207e2ef96de354de7d0002292ba1503538fc77b"
|
||||
integrity sha512-SX/uKq52cuxm4YFXWFaVByaSHJh2w3BnokVSeUJVCv6K7WulT9u2BuNRBhuFl8vAuYnzx9bEu9WgpcNYTrYieg==
|
||||
dependencies:
|
||||
"@noble/hashes" "~1.3.0"
|
||||
"@scure/base" "~1.1.0"
|
||||
|
||||
"@types/long@^4.0.1":
|
||||
version "4.0.2"
|
||||
resolved "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a"
|
||||
integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==
|
||||
|
||||
"@types/node@>=12.12.47", "@types/node@>=13.7.0":
|
||||
version "18.16.3"
|
||||
resolved "https://registry.npmjs.org/@types/node/-/node-18.16.3.tgz#6bda7819aae6ea0b386ebc5b24bdf602f1b42b01"
|
||||
integrity sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q==
|
||||
|
||||
"@wagmi/chains@0.2.16":
|
||||
version "0.2.16"
|
||||
resolved "https://registry.npmjs.org/@wagmi/chains/-/chains-0.2.16.tgz#a726716e4619ec1c192b312e23f9c38407617aa0"
|
||||
integrity sha512-rkWaI2PxCnbD8G07ZZff5QXftnSkYL0h5f4DkHCG3fGYYr/ZDvmCL4bMae7j7A9sAif1csPPBmbCzHp3R5ogCQ==
|
||||
|
||||
abitype@0.7.1:
|
||||
version "0.7.1"
|
||||
resolved "https://registry.npmjs.org/abitype/-/abitype-0.7.1.tgz#16db20abe67de80f6183cf75f3de1ff86453b745"
|
||||
integrity sha512-VBkRHTDZf9Myaek/dO3yMmOzB/y2s3Zo6nVU7yaw1G+TvCHAjwaJzNGN9yo4K5D8bU/VZXKP1EJpRhFr862PlQ==
|
||||
|
||||
abort-controller@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
|
||||
integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
|
||||
dependencies:
|
||||
event-target-shim "^5.0.0"
|
||||
|
||||
aes-js@4.0.0-beta.3:
|
||||
version "4.0.0-beta.3"
|
||||
resolved "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.3.tgz#da2253f0ff03a0b3a9e445c8cbdf78e7fda7d48c"
|
||||
integrity sha512-/xJX0/VTPcbc5xQE2VUP91y1xN8q/rDfhEzLm+vLc3hYvb5+qHCnpJRuFcrKn63zumK/sCwYYzhG8HP78JYSTA==
|
||||
|
||||
ansi-regex@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
||||
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||
|
||||
ansi-styles@^4.0.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
|
||||
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
|
||||
dependencies:
|
||||
color-convert "^2.0.1"
|
||||
|
||||
atomic-sleep@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b"
|
||||
integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==
|
||||
|
||||
base64-js@^1.3.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
|
||||
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
|
||||
|
||||
bn.js@^4.11.9:
|
||||
version "4.12.0"
|
||||
resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
|
||||
integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
|
||||
|
||||
bn.js@^5.2.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70"
|
||||
integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==
|
||||
|
||||
brorand@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
|
||||
integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==
|
||||
|
||||
buffer-from@^1.0.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
|
||||
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
|
||||
|
||||
buffer@^6.0.3:
|
||||
version "6.0.3"
|
||||
resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
|
||||
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
|
||||
dependencies:
|
||||
base64-js "^1.3.1"
|
||||
ieee754 "^1.2.1"
|
||||
|
||||
cliui@^8.0.1:
|
||||
version "8.0.1"
|
||||
resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
|
||||
integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
|
||||
dependencies:
|
||||
string-width "^4.2.0"
|
||||
strip-ansi "^6.0.1"
|
||||
wrap-ansi "^7.0.0"
|
||||
|
||||
color-convert@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
|
||||
dependencies:
|
||||
color-name "~1.1.4"
|
||||
|
||||
color-name@~1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
elliptic@6.5.4:
|
||||
version "6.5.4"
|
||||
resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
|
||||
integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
|
||||
dependencies:
|
||||
bn.js "^4.11.9"
|
||||
brorand "^1.1.0"
|
||||
hash.js "^1.0.0"
|
||||
hmac-drbg "^1.0.1"
|
||||
inherits "^2.0.4"
|
||||
minimalistic-assert "^1.0.1"
|
||||
minimalistic-crypto-utils "^1.0.1"
|
||||
|
||||
emoji-regex@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
|
||||
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
|
||||
|
||||
esbuild@~0.17.6:
|
||||
version "0.17.18"
|
||||
resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.17.18.tgz#f4f8eb6d77384d68cd71c53eb6601c7efe05e746"
|
||||
integrity sha512-z1lix43jBs6UKjcZVKOw2xx69ffE2aG0PygLL5qJ9OS/gy0Ewd1gW/PUQIOIQGXBHWNywSc0floSKoMFF8aK2w==
|
||||
optionalDependencies:
|
||||
"@esbuild/android-arm" "0.17.18"
|
||||
"@esbuild/android-arm64" "0.17.18"
|
||||
"@esbuild/android-x64" "0.17.18"
|
||||
"@esbuild/darwin-arm64" "0.17.18"
|
||||
"@esbuild/darwin-x64" "0.17.18"
|
||||
"@esbuild/freebsd-arm64" "0.17.18"
|
||||
"@esbuild/freebsd-x64" "0.17.18"
|
||||
"@esbuild/linux-arm" "0.17.18"
|
||||
"@esbuild/linux-arm64" "0.17.18"
|
||||
"@esbuild/linux-ia32" "0.17.18"
|
||||
"@esbuild/linux-loong64" "0.17.18"
|
||||
"@esbuild/linux-mips64el" "0.17.18"
|
||||
"@esbuild/linux-ppc64" "0.17.18"
|
||||
"@esbuild/linux-riscv64" "0.17.18"
|
||||
"@esbuild/linux-s390x" "0.17.18"
|
||||
"@esbuild/linux-x64" "0.17.18"
|
||||
"@esbuild/netbsd-x64" "0.17.18"
|
||||
"@esbuild/openbsd-x64" "0.17.18"
|
||||
"@esbuild/sunos-x64" "0.17.18"
|
||||
"@esbuild/win32-arm64" "0.17.18"
|
||||
"@esbuild/win32-ia32" "0.17.18"
|
||||
"@esbuild/win32-x64" "0.17.18"
|
||||
|
||||
escalade@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
||||
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
|
||||
|
||||
ethers@~6.2.1:
|
||||
version "6.2.3"
|
||||
resolved "https://registry.npmjs.org/ethers/-/ethers-6.2.3.tgz#9ddee438b5949e9724ba4c5d2c3b8deb5202ce96"
|
||||
integrity sha512-l1Z/Yr+HrOk+7LTeYRHGMvYwVLGpTuVrT/kJ7Kagi3nekGISYILIby0f1ipV9BGzgERyy+w4emH+d3PhhcxIfA==
|
||||
dependencies:
|
||||
"@adraffy/ens-normalize" "1.9.0"
|
||||
"@noble/hashes" "1.1.2"
|
||||
"@noble/secp256k1" "1.7.1"
|
||||
aes-js "4.0.0-beta.3"
|
||||
tslib "2.4.0"
|
||||
ws "8.5.0"
|
||||
|
||||
event-target-shim@^5.0.0:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
|
||||
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
|
||||
|
||||
events@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
|
||||
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
|
||||
|
||||
fast-redact@^3.1.1:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.npmjs.org/fast-redact/-/fast-redact-3.1.2.tgz#d58e69e9084ce9fa4c1a6fa98a3e1ecf5d7839aa"
|
||||
integrity sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==
|
||||
|
||||
fsevents@~2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
||||
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
||||
|
||||
get-caller-file@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||
|
||||
get-tsconfig@^4.4.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.5.0.tgz#6d52d1c7b299bd3ee9cd7638561653399ac77b0f"
|
||||
integrity sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ==
|
||||
|
||||
hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3:
|
||||
version "1.1.7"
|
||||
resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
|
||||
integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
minimalistic-assert "^1.0.1"
|
||||
|
||||
hmac-drbg@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
||||
integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==
|
||||
dependencies:
|
||||
hash.js "^1.0.3"
|
||||
minimalistic-assert "^1.0.0"
|
||||
minimalistic-crypto-utils "^1.0.1"
|
||||
|
||||
ieee754@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||
|
||||
inherits@^2.0.3, inherits@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
is-fullwidth-code-point@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
|
||||
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
|
||||
|
||||
isomorphic-ws@5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf"
|
||||
integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==
|
||||
|
||||
js-sha3@0.8.0:
|
||||
version "0.8.0"
|
||||
resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"
|
||||
integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==
|
||||
|
||||
kysely-postgres-js@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/kysely-postgres-js/-/kysely-postgres-js-1.1.1.tgz#d53a738403632f03d3a00c115af01b62a5f8c9c1"
|
||||
integrity sha512-4liHLEA1TfdGVixiW2wM4UFqv0r+F06pxpFng7xSdyl4p6lUp0099W+jotq4inovneTbVDBaFKwn+uOiORXKGQ==
|
||||
|
||||
kysely@^0.24.2:
|
||||
version "0.24.2"
|
||||
resolved "https://registry.npmjs.org/kysely/-/kysely-0.24.2.tgz#caf3be037939bd20449c0b7840e932f074b4d12c"
|
||||
integrity sha512-+7eaTJNUYm2yRq1x+lEOZc+78TO35dTZ9b0dh49+Z9CTt2byMSbMiOKpwPlOyCAaHD4kILkAYWYZNywFlmBwRA==
|
||||
|
||||
lodash.camelcase@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
|
||||
integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==
|
||||
|
||||
long@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
|
||||
integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
|
||||
|
||||
long@^5.0.0:
|
||||
version "5.2.3"
|
||||
resolved "https://registry.npmjs.org/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1"
|
||||
integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==
|
||||
|
||||
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
|
||||
integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
|
||||
|
||||
minimalistic-crypto-utils@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
|
||||
integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==
|
||||
|
||||
neverthrow@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.npmjs.org/neverthrow/-/neverthrow-6.0.0.tgz#bacd7661cade296ccc5c35760bb3b679214155b6"
|
||||
integrity sha512-kPZKRs4VkdloCGQXPoP84q4sT/1Z+lYM61AXyV8wWa2hnuo5KpPBF2S3crSFnMrOgUISmEBP8Vo/ngGZX60NhA==
|
||||
|
||||
on-exit-leak-free@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz#5c703c968f7e7f851885f6459bf8a8a57edc9cc4"
|
||||
integrity sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==
|
||||
|
||||
pino-abstract-transport@v1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz#cc0d6955fffcadb91b7b49ef220a6cc111d48bb3"
|
||||
integrity sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==
|
||||
dependencies:
|
||||
readable-stream "^4.0.0"
|
||||
split2 "^4.0.0"
|
||||
|
||||
pino-std-serializers@^6.0.0:
|
||||
version "6.2.1"
|
||||
resolved "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.1.tgz#369f4ae2a19eb6d769ddf2c88a2164b76879a284"
|
||||
integrity sha512-wHuWB+CvSVb2XqXM0W/WOYUkVSPbiJb9S5fNB7TBhd8s892Xq910bRxwHtC4l71hgztObTjXL6ZheZXFjhDrDQ==
|
||||
|
||||
pino@^8.12.1:
|
||||
version "8.12.1"
|
||||
resolved "https://registry.npmjs.org/pino/-/pino-8.12.1.tgz#9aca3c733b221a5894ee58b2e070c66dd3e89fcf"
|
||||
integrity sha512-n4F7nrEUDH0u5pjlUPkrvsN6oZOhScZWwpWPniwVkMnO6a2DhpnMNWDUlW0SawVICgrNhOf0yTNgw2lYQBsPYA==
|
||||
dependencies:
|
||||
atomic-sleep "^1.0.0"
|
||||
fast-redact "^3.1.1"
|
||||
on-exit-leak-free "^2.1.0"
|
||||
pino-abstract-transport v1.0.0
|
||||
pino-std-serializers "^6.0.0"
|
||||
process-warning "^2.0.0"
|
||||
quick-format-unescaped "^4.0.3"
|
||||
real-require "^0.2.0"
|
||||
safe-stable-stringify "^2.3.1"
|
||||
sonic-boom "^3.1.0"
|
||||
thread-stream "^2.0.0"
|
||||
|
||||
postgres@^3.3.4:
|
||||
version "3.3.4"
|
||||
resolved "https://registry.npmjs.org/postgres/-/postgres-3.3.4.tgz#09635eb9fae26dd449db9b1bd3956ef56c5b78fa"
|
||||
integrity sha512-XVu0+d/Y56pl2lSaf0c7V19AhAEfpVrhID1IENWN8nf0xch6hFq6dAov5dtUX6ZD46wfr1TxvLhxLtV8WnNsOg==
|
||||
|
||||
process-warning@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz#008ec76b579820a8e5c35d81960525ca64feb626"
|
||||
integrity sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==
|
||||
|
||||
process@^0.11.10:
|
||||
version "0.11.10"
|
||||
resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
|
||||
integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
|
||||
|
||||
protobufjs@^7.0.0:
|
||||
version "7.2.3"
|
||||
resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.3.tgz#01af019e40d9c6133c49acbb3ff9e30f4f0f70b2"
|
||||
integrity sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg==
|
||||
dependencies:
|
||||
"@protobufjs/aspromise" "^1.1.2"
|
||||
"@protobufjs/base64" "^1.1.2"
|
||||
"@protobufjs/codegen" "^2.0.4"
|
||||
"@protobufjs/eventemitter" "^1.1.0"
|
||||
"@protobufjs/fetch" "^1.1.0"
|
||||
"@protobufjs/float" "^1.0.2"
|
||||
"@protobufjs/inquire" "^1.1.0"
|
||||
"@protobufjs/path" "^1.1.2"
|
||||
"@protobufjs/pool" "^1.1.0"
|
||||
"@protobufjs/utf8" "^1.1.0"
|
||||
"@types/node" ">=13.7.0"
|
||||
long "^5.0.0"
|
||||
|
||||
quick-format-unescaped@^4.0.3:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7"
|
||||
integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==
|
||||
|
||||
readable-stream@^4.0.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz#0914d0c72db03b316c9733bb3461d64a3cc50cba"
|
||||
integrity sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==
|
||||
dependencies:
|
||||
abort-controller "^3.0.0"
|
||||
buffer "^6.0.3"
|
||||
events "^3.3.0"
|
||||
process "^0.11.10"
|
||||
|
||||
real-require@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz#209632dea1810be2ae063a6ac084fee7e33fba78"
|
||||
integrity sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==
|
||||
|
||||
require-directory@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||
integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
|
||||
|
||||
safe-stable-stringify@^2.3.1:
|
||||
version "2.4.3"
|
||||
resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886"
|
||||
integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==
|
||||
|
||||
sonic-boom@^3.1.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz#cffab6dafee3b2bcb88d08d589394198bee1838c"
|
||||
integrity sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==
|
||||
dependencies:
|
||||
atomic-sleep "^1.0.0"
|
||||
|
||||
source-map-support@^0.5.21:
|
||||
version "0.5.21"
|
||||
resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
|
||||
integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
|
||||
dependencies:
|
||||
buffer-from "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
source-map@^0.6.0:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
|
||||
split2@^4.0.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4"
|
||||
integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==
|
||||
|
||||
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.1"
|
||||
|
||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
thread-stream@^2.0.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.npmjs.org/thread-stream/-/thread-stream-2.3.0.tgz#4fc07fb39eff32ae7bad803cb7dd9598349fed33"
|
||||
integrity sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==
|
||||
dependencies:
|
||||
real-require "^0.2.0"
|
||||
|
||||
tiny-typed-emitter@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz#b3b027fdd389ff81a152c8e847ee2f5be9fad7b5"
|
||||
integrity sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==
|
||||
|
||||
tslib@2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
|
||||
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
|
||||
|
||||
tsx@^3.12.5:
|
||||
version "3.12.7"
|
||||
resolved "https://registry.npmjs.org/tsx/-/tsx-3.12.7.tgz#b3b8b0fc79afc8260d1e14f9e995616c859a91e9"
|
||||
integrity sha512-C2Ip+jPmqKd1GWVQDvz/Eyc6QJbGfE7NrR3fx5BpEHMZsEHoIxHL1j+lKdGobr8ovEyqeNkPLSKp6SCSOt7gmw==
|
||||
dependencies:
|
||||
"@esbuild-kit/cjs-loader" "^2.4.2"
|
||||
"@esbuild-kit/core-utils" "^3.0.0"
|
||||
"@esbuild-kit/esm-loader" "^2.5.5"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
typescript@^5.0.0:
|
||||
version "5.0.4"
|
||||
resolved "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b"
|
||||
integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==
|
||||
|
||||
viem@^0.3.2:
|
||||
version "0.3.17"
|
||||
resolved "https://registry.npmjs.org/viem/-/viem-0.3.17.tgz#2f4d01c5988f2a90ef52acb84a0dc9f7c2822538"
|
||||
integrity sha512-WGJQ3rV2gMiHgwxLqeAZQ3HetSfsrkF//WezdJPnwUNXuic/c2jjB3MBk4XfYvuRUMccPfc37ORi03AmQxjscg==
|
||||
dependencies:
|
||||
"@adraffy/ens-normalize" "1.9.0"
|
||||
"@noble/curves" "0.9.0"
|
||||
"@noble/hashes" "1.3.0"
|
||||
"@scure/bip32" "1.2.0"
|
||||
"@scure/bip39" "1.2.0"
|
||||
"@wagmi/chains" "0.2.16"
|
||||
abitype "0.7.1"
|
||||
isomorphic-ws "5.0.0"
|
||||
ws "8.12.0"
|
||||
|
||||
wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
dependencies:
|
||||
ansi-styles "^4.0.0"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
ws@8.12.0:
|
||||
version "8.12.0"
|
||||
resolved "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz#485074cc392689da78e1828a9ff23585e06cddd8"
|
||||
integrity sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==
|
||||
|
||||
ws@8.5.0:
|
||||
version "8.5.0"
|
||||
resolved "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f"
|
||||
integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==
|
||||
|
||||
y18n@^5.0.5:
|
||||
version "5.0.8"
|
||||
resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
|
||||
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
|
||||
|
||||
yargs-parser@^21.1.1:
|
||||
version "21.1.1"
|
||||
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
|
||||
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
|
||||
|
||||
yargs@^17.7.2:
|
||||
version "17.7.2"
|
||||
resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
|
||||
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
|
||||
dependencies:
|
||||
cliui "^8.0.1"
|
||||
escalade "^3.1.1"
|
||||
get-caller-file "^2.0.5"
|
||||
require-directory "^2.1.1"
|
||||
string-width "^4.2.3"
|
||||
y18n "^5.0.5"
|
||||
yargs-parser "^21.1.1"
|
||||
Reference in New Issue
Block a user