feat: added a new job blockChain-block-number
This commit is contained in:
parent
5f7d4fe72e
commit
9d336c0c4d
@ -22,6 +22,6 @@
|
|||||||
// examples, and because it is not a recommended rule, you should either
|
// examples, and because it is not a recommended rule, you should either
|
||||||
// disable it, or understand what it enforces.
|
// disable it, or understand what it enforces.
|
||||||
// https://typescript-eslint.io/rules/explicit-function-return-type/
|
// https://typescript-eslint.io/rules/explicit-function-return-type/
|
||||||
"@typescript-eslint/explicit-function-return-type": "warn"
|
// "@typescript-eslint/explicit-function-return-type": "warn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node build/src/main.js",
|
"start": "node build/src/main.js",
|
||||||
"clean": "rimraf coverage build tmp",
|
"clean": "rimraf coverage build tmp",
|
||||||
"prebuild": "npm run lint",
|
"_prebuild": "npm run lint",
|
||||||
"build": "tsc -p tsconfig.json",
|
"build": "tsc -p tsconfig.json",
|
||||||
"build:watch": "tsc -w -p tsconfig.json",
|
"build:watch": "tsc -w -p tsconfig.json",
|
||||||
"build:release": "npm run clean && tsc -p tsconfig.release.json",
|
"build:release": "npm run clean && tsc -p tsconfig.release.json",
|
||||||
@ -41,7 +41,7 @@
|
|||||||
"author": "pablof7z",
|
"author": "pablof7z",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nostr-dev-kit/ndk": "^0.7.5",
|
"@nostr-dev-kit/ndk": "^0.8.1",
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"file-type": "^18.5.0",
|
"file-type": "^18.5.0",
|
||||||
|
5884
pnpm-lock.yaml
5884
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
45
src/job-types/blockChain-block-number.ts
Normal file
45
src/job-types/blockChain-block-number.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { NDKEvent } from '@nostr-dev-kit/ndk';
|
||||||
|
import { log } from '../main.js';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export async function blockChainBlockNumberJob(
|
||||||
|
event: NDKEvent,
|
||||||
|
): Promise<string> {
|
||||||
|
log('New blockChain-block-number job', event.rawEvent());
|
||||||
|
|
||||||
|
const input = event.tagValue('i');
|
||||||
|
|
||||||
|
const blockChainUrl = `https://blockchain.info/blocks/${input}?format=json`;
|
||||||
|
|
||||||
|
console.log('blockChainUrl :>> ', blockChainUrl);
|
||||||
|
|
||||||
|
const output = await axios
|
||||||
|
.get(blockChainUrl)
|
||||||
|
.then((res) => {
|
||||||
|
const closestObject = findClosestObject(res.data, input);
|
||||||
|
return closestObject.block_index.toString();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log('err in blockChain request :>> ', err);
|
||||||
|
return Promise.reject(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: define type for array
|
||||||
|
// Function to find the object with the closest timestamp
|
||||||
|
function findClosestObject(array, timestamp) {
|
||||||
|
let closestObject = null;
|
||||||
|
let minDifference = Infinity;
|
||||||
|
|
||||||
|
array.forEach((obj) => {
|
||||||
|
const difference = Math.abs(obj.time - timestamp);
|
||||||
|
if (difference < minDifference) {
|
||||||
|
minDifference = difference;
|
||||||
|
closestObject = obj;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return closestObject;
|
||||||
|
}
|
148
src/main.ts
148
src/main.ts
@ -8,59 +8,91 @@ import { inProgress } from './jobs/reactions/in-progress.js';
|
|||||||
import { publishStatus } from './jobs/reactions/status.js';
|
import { publishStatus } from './jobs/reactions/status.js';
|
||||||
import { priceJob } from './jobs/price.js';
|
import { priceJob } from './jobs/price.js';
|
||||||
import { getConfig } from './config/index.js';
|
import { getConfig } from './config/index.js';
|
||||||
import { decode } from "light-bolt11-decoder";
|
import { decode } from 'light-bolt11-decoder';
|
||||||
import { checkInvoiceStatus } from './utils/lnbits.js';
|
import { checkInvoiceStatus } from './utils/lnbits.js';
|
||||||
|
import { blockChainBlockNumberJob } from './job-types/blockChain-block-number.js';
|
||||||
|
|
||||||
export const log = debug('fool-me-once-dvm');
|
export const log = debug('fool-me-once-dvm');
|
||||||
|
|
||||||
export const configFile = process.argv[2] || `${process.env.HOME}/.fool-me-once.json`;
|
export const configFile =
|
||||||
|
process.argv[2] || `${process.env.HOME}/.fool-me-once.json`;
|
||||||
|
|
||||||
log('configFile', {configFile});
|
log('configFile', { configFile });
|
||||||
|
|
||||||
export const ndk = new NDK({
|
export const ndk = new NDK({
|
||||||
explicitRelayUrls: [
|
explicitRelayUrls: [
|
||||||
'wss://relay.f7z.io'
|
'wss://relay.damus.io',
|
||||||
|
'wss://relay.primal.net',
|
||||||
|
'wss://relayable.org',
|
||||||
],
|
],
|
||||||
signer: getSigner(),
|
signer: getSigner(),
|
||||||
})
|
});
|
||||||
await ndk.connect(2000);
|
await ndk.connect(2000);
|
||||||
log('connected')
|
log('connected');
|
||||||
|
|
||||||
const subs = ndk.subscribe({
|
const subs = ndk.subscribe(
|
||||||
kinds: [68001],
|
{
|
||||||
|
kinds: [68001 as number],
|
||||||
since: Math.floor(Date.now() / 1000),
|
since: Math.floor(Date.now() / 1000),
|
||||||
"#j": ["summarize", "explain"],
|
'#j': ['summarize', 'explain'],
|
||||||
}, { closeOnEose: false })
|
},
|
||||||
|
{ closeOnEose: false },
|
||||||
|
);
|
||||||
|
|
||||||
const speechToTextSub = ndk.subscribe({
|
const speechToTextSub = ndk.subscribe(
|
||||||
kinds: [68001],
|
{
|
||||||
|
kinds: [68001 as number],
|
||||||
since: Math.floor(Date.now() / 1000),
|
since: Math.floor(Date.now() / 1000),
|
||||||
"#j": ["speech-to-text"],
|
'#j': ['speech-to-text'],
|
||||||
}, { closeOnEose: false })
|
},
|
||||||
|
{ closeOnEose: false },
|
||||||
|
);
|
||||||
|
|
||||||
subs.on("event", (e) => processJobEvent(e, 'summarize'));
|
const blockChainBlockNumberSub = ndk.subscribe(
|
||||||
speechToTextSub.on("event", (e) => processJobEvent(e, 'speech-to-text'));
|
{
|
||||||
|
kinds: [68001 as number],
|
||||||
|
since: Math.floor(Date.now() / 1000),
|
||||||
|
'#j': ['blockChain-block-number'],
|
||||||
|
},
|
||||||
|
{ closeOnEose: false },
|
||||||
|
);
|
||||||
|
|
||||||
type JobType = "summarize" | "explain" | "speech-to-text";
|
subs.on('event', (e) => processJobEvent(e, 'summarize'));
|
||||||
|
speechToTextSub.on('event', (e) => processJobEvent(e, 'speech-to-text'));
|
||||||
|
blockChainBlockNumberSub.on('event', (e) =>
|
||||||
|
processJobEvent(e, 'blockChain-block-number'),
|
||||||
|
);
|
||||||
|
|
||||||
|
type JobType =
|
||||||
|
| 'summarize'
|
||||||
|
| 'explain'
|
||||||
|
| 'speech-to-text'
|
||||||
|
| 'blockChain-block-number';
|
||||||
|
|
||||||
async function processJobEvent(event: NDKEvent, type: JobType): Promise<void> {
|
async function processJobEvent(event: NDKEvent, type: JobType): Promise<void> {
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
let jobAmount = await priceJob(event);
|
let jobAmount =
|
||||||
|
type === 'blockChain-block-number' ? 0 : await priceJob(event);
|
||||||
let output: any;
|
let output: any;
|
||||||
let payReqEvent: NDKEvent;
|
let payReqEvent: NDKEvent;
|
||||||
let paidAmount = 0;
|
let paidAmount = 0;
|
||||||
|
|
||||||
const waitForPaymentBeforeProcessing = (): boolean => {
|
const waitForPaymentBeforeProcessing = (): boolean => {
|
||||||
const processWithoutPaymentLimit = config.processWithoutPaymentLimit ?? 500;
|
const processWithoutPaymentLimit =
|
||||||
log('waitForPaymentBeforeProcessing', {jobAmount, processWithoutPaymentLimit});
|
config.processWithoutPaymentLimit ?? 500;
|
||||||
return jobAmount && jobAmount > (processWithoutPaymentLimit * 1000);
|
log('waitForPaymentBeforeProcessing', {
|
||||||
}
|
jobAmount,
|
||||||
|
processWithoutPaymentLimit,
|
||||||
|
});
|
||||||
|
return jobAmount && jobAmount > processWithoutPaymentLimit * 1000;
|
||||||
|
};
|
||||||
|
|
||||||
const waitForPaymentBeforePublishingResult = (): boolean => {
|
const waitForPaymentBeforePublishingResult = (): boolean => {
|
||||||
const serveResultsWithoutPaymentLimit = config.serveResultsWithoutPaymentLimit ?? 1000;
|
const serveResultsWithoutPaymentLimit =
|
||||||
log('waitForPaymentBeforeProcessing', {jobAmount});
|
config.serveResultsWithoutPaymentLimit ?? 1000;
|
||||||
return jobAmount && jobAmount > (serveResultsWithoutPaymentLimit * 1000);
|
log('waitForPaymentBeforeProcessing', { jobAmount });
|
||||||
}
|
return jobAmount && jobAmount > serveResultsWithoutPaymentLimit * 1000;
|
||||||
|
};
|
||||||
|
|
||||||
const missingAmount = (): number => jobAmount - paidAmount;
|
const missingAmount = (): number => jobAmount - paidAmount;
|
||||||
|
|
||||||
@ -70,14 +102,17 @@ async function processJobEvent(event: NDKEvent, type: JobType): Promise<void> {
|
|||||||
if (config.undercut) {
|
if (config.undercut) {
|
||||||
startUndercutting();
|
startUndercutting();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const startUndercutting = async (): Promise<void> => {
|
const startUndercutting = async (): Promise<void> => {
|
||||||
const undercutSub = ndk.subscribe({
|
const undercutSub = ndk.subscribe(
|
||||||
kinds: [68002, 68003],
|
{
|
||||||
...event.filter()
|
kinds: [68002 as number, 68003 as number],
|
||||||
}, { closeOnEose: false, groupable: false });
|
...event.filter(),
|
||||||
undercutSub.on("event", async (e) => {
|
},
|
||||||
|
{ closeOnEose: false, groupable: false },
|
||||||
|
);
|
||||||
|
undercutSub.on('event', async (e) => {
|
||||||
if (e.pubkey === payReqEvent.pubkey) return;
|
if (e.pubkey === payReqEvent.pubkey) return;
|
||||||
|
|
||||||
// check if this is a payment request
|
// check if this is a payment request
|
||||||
@ -97,14 +132,17 @@ async function processJobEvent(event: NDKEvent, type: JobType): Promise<void> {
|
|||||||
payReqEvent = await requirePayment(event, jobAmount, true);
|
payReqEvent = await requirePayment(event, jobAmount, true);
|
||||||
}, 5000);
|
}, 5000);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
const waitForPaymentViaZap = (payReqEvent, resolve, reject) => {
|
const waitForPaymentViaZap = (payReqEvent, resolve, reject) => {
|
||||||
const zapmon = ndk.subscribe({
|
const zapmon = ndk.subscribe(
|
||||||
|
{
|
||||||
kinds: [68002, 9735],
|
kinds: [68002, 9735],
|
||||||
...payReqEvent.filter()
|
...payReqEvent.filter(),
|
||||||
}, { closeOnEose: false });
|
},
|
||||||
zapmon.on("event", (e) => {
|
{ closeOnEose: false },
|
||||||
|
);
|
||||||
|
zapmon.on('event', (e) => {
|
||||||
log(`received a ${e.kind} for the payment request`, e.rawEvent());
|
log(`received a ${e.kind} for the payment request`, e.rawEvent());
|
||||||
|
|
||||||
// TODO: validate amount, zapper, etc
|
// TODO: validate amount, zapper, etc
|
||||||
@ -115,11 +153,11 @@ async function processJobEvent(event: NDKEvent, type: JobType): Promise<void> {
|
|||||||
// zapmon.close();
|
// zapmon.close();
|
||||||
resolve();
|
resolve();
|
||||||
} else if (e.kind === 68003) {
|
} else if (e.kind === 68003) {
|
||||||
zapmon.close();
|
zapmon.stop();
|
||||||
reject();
|
reject();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
const waitForPaymentViaLNInvoice = (payReqEvent, resolve) => {
|
const waitForPaymentViaLNInvoice = (payReqEvent, resolve) => {
|
||||||
const amountTag = payReqEvent.getMatchingTags('amount')[0];
|
const amountTag = payReqEvent.getMatchingTags('amount')[0];
|
||||||
@ -129,8 +167,8 @@ async function processJobEvent(event: NDKEvent, type: JobType): Promise<void> {
|
|||||||
|
|
||||||
const invoice = decode(bolt11);
|
const invoice = decode(bolt11);
|
||||||
const pr = invoice.payment_hash;
|
const pr = invoice.payment_hash;
|
||||||
log({invoice});
|
log({ invoice });
|
||||||
log({pr});
|
log({ pr });
|
||||||
|
|
||||||
const checkInterval = setInterval(() => {
|
const checkInterval = setInterval(() => {
|
||||||
checkInvoiceStatus(invoice).then((status) => {
|
checkInvoiceStatus(invoice).then((status) => {
|
||||||
@ -140,40 +178,44 @@ async function processJobEvent(event: NDKEvent, type: JobType): Promise<void> {
|
|||||||
clearInterval(checkInterval);
|
clearInterval(checkInterval);
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
};
|
||||||
|
|
||||||
const waitForPayment = async (payReqEvent: NDKEvent): Promise<void> => {
|
const waitForPayment = async (payReqEvent: NDKEvent): Promise<void> => {
|
||||||
log('waitForPayment');
|
log('waitForPayment');
|
||||||
const promise = new Promise<void>((resolve, reject) => {
|
const promise = new Promise<void>((resolve, reject) => {
|
||||||
waitForPaymentViaZap(payReqEvent, resolve, reject)
|
waitForPaymentViaZap(payReqEvent, resolve, reject);
|
||||||
waitForPaymentViaLNInvoice(payReqEvent, resolve)
|
waitForPaymentViaLNInvoice(payReqEvent, resolve);
|
||||||
});
|
});
|
||||||
|
|
||||||
return promise;
|
return promise;
|
||||||
}
|
};
|
||||||
|
|
||||||
const startProcessing = async () => {
|
const startProcessing = async () => {
|
||||||
log('startProcessing');
|
log('startProcessing');
|
||||||
inProgress(event);
|
await inProgress(event);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "summarize": {
|
case 'summarize': {
|
||||||
output = await onNewSummarizationJob(event);
|
output = await onNewSummarizationJob(event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "speech-to-text": {
|
case 'speech-to-text': {
|
||||||
output = await speechToTextJob(event);
|
output = await speechToTextJob(event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'blockChain-block-number': {
|
||||||
|
output = await blockChainBlockNumberJob(event);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const publishResult = (): void => {
|
const publishResult = (): void => {
|
||||||
log('publishResult');
|
log('publishResult');
|
||||||
complete(event, missingAmount(), { output });
|
complete(event, missingAmount(), { output });
|
||||||
}
|
};
|
||||||
|
|
||||||
await validateJobRequest(event);
|
await validateJobRequest(event);
|
||||||
|
|
||||||
@ -184,12 +226,14 @@ async function processJobEvent(event: NDKEvent, type: JobType): Promise<void> {
|
|||||||
|
|
||||||
await startProcessing();
|
await startProcessing();
|
||||||
|
|
||||||
await publishStatus(event, 'finished');
|
await publishStatus(event, 'finished').catch((err) =>
|
||||||
|
console.log('err :>> ', err),
|
||||||
|
);
|
||||||
|
|
||||||
if (jobAmount > paidAmount && waitForPaymentBeforePublishingResult()) {
|
if (jobAmount > paidAmount && waitForPaymentBeforePublishingResult()) {
|
||||||
await reqPayment();
|
await reqPayment();
|
||||||
await waitForPayment(payReqEvent);
|
await waitForPayment(payReqEvent);
|
||||||
log(`done with wait for publish`)
|
log(`done with wait for publish`);
|
||||||
}
|
}
|
||||||
|
|
||||||
await publishResult();
|
await publishResult();
|
||||||
|
Loading…
Reference in New Issue
Block a user