brainchain-worker 0.18.1 → 0.18.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/bond.js +29 -9
  2. package/package.json +1 -1
package/dist/bond.js CHANGED
@@ -182,8 +182,8 @@ export function createBondChain(network, config, account, fetcher = fetch) {
182
182
  export const bondGas = (gasPrice, approves) => (GAS.create + (approves ? GAS.approve : 0n)) * gasPrice;
183
183
  const fee = (amount) => (amount * FEE_BPS) / BPS;
184
184
  /** Where a bond stands, in one line. */
185
- export function bondLine(network, b, indexed, now) {
186
- const head = `Bond No. ${b.deed} on task ${b.task}: ${usdg(network, b.amount)}`;
185
+ export function bondLine(network, b, indexed, now, page) {
186
+ const head = `Bond No. ${page?.number ?? b.deed} on task ${b.task}: ${usdg(network, b.amount)}`;
187
187
  if (b.status === DeedStatus.Settled) {
188
188
  if (b.remainderBps === Number(BPS))
189
189
  return `${head}, delivered at ${when(b.settledAt)}: ${usdg(network, b.amount - fee(b.amount))} back after Shipped's 1% fee (bond claim ${b.task} collects it)`;
@@ -204,6 +204,21 @@ function closed(network, config) {
204
204
  return "Bonds are not open yet: BrainChain's ProofIndex on Robinhood Chain, which a bond's check reads, is not deployed. A later release of brainchain-worker names it.";
205
205
  return undefined;
206
206
  }
207
+ /** Shipped's own number and page for a deed; the registry id stands in when the API cannot be reached or the bond is a test. */
208
+ export const SHIPPED_API = "https://api.shipped.bond";
209
+ export async function deedPage(deed, fetchImpl = fetch) {
210
+ try {
211
+ const response = await fetchImpl(`${SHIPPED_API}/v1/deeds/${deed}`, { signal: AbortSignal.timeout(5_000) });
212
+ if (!response.ok)
213
+ return undefined;
214
+ const body = (await response.json());
215
+ const { number, url } = body.deed ?? {};
216
+ return typeof number === "string" && typeof url === "string" ? { number, url } : undefined;
217
+ }
218
+ catch {
219
+ return undefined;
220
+ }
221
+ }
207
222
  /** Reads the task, says what the bond costs and what it does, and sends the approval and the bond. */
208
223
  export async function bond(network, config, chain, task, options) {
209
224
  const { log } = options;
@@ -217,8 +232,8 @@ export async function bond(network, config, chain, task, options) {
217
232
  if (t.poster.toLowerCase() === chain.account.toLowerCase())
218
233
  throw new Error(`Task ${task} was posted by this wallet. A bond guarantees delivery to someone else: it earns no standing on a task the worker posted itself.`);
219
234
  const hiredHere = t.status === Status.Hired && t.model.toLowerCase().endsWith(chain.account.slice(2).toLowerCase());
220
- if (t.status !== Status.Open && !hiredHere)
221
- throw new Error(`Task ${task} is not open and not hired to this worker, so there is nothing to bond.`);
235
+ if (!hiredHere)
236
+ throw new Error(`Task ${task} is not hired to this worker. Bond a task after Jev hires you for it.`);
222
237
  const now = await chain.now();
223
238
  if (t.deadline <= now)
224
239
  throw new Error(`Task ${task}'s deadline, ${when(t.deadline)}, has passed.`);
@@ -262,19 +277,24 @@ export async function bond(network, config, chain, task, options) {
262
277
  }
263
278
  log(`Bonding ${usdg(network, options.amount)} on task ${task}...`);
264
279
  const { deed, tx } = await chain.create(terms, options.amount);
265
- log(`Bond No. ${deed} is open on Shipped (${tx}). Jev reads it when it hires; \`bond status ${task}\` follows it.`);
280
+ const page = await deedPage(deed, options.fetch);
281
+ log(page
282
+ ? `Bond No. ${page.number} is open on Shipped: ${page.url} (${tx}). Jev reads it when it hires; \`bond status ${task}\` follows it.`
283
+ : `Bond No. ${deed} is open on Shipped (${tx}). Jev reads it when it hires; \`bond status ${task}\` follows it.`);
266
284
  }
267
285
  /** Prints where the worker's bonds on a task stand. */
268
- export async function bondStatus(network, config, chain, task, log) {
286
+ export async function bondStatus(network, config, chain, task, log, fetchImpl = fetch) {
269
287
  const shut = closed(network, config);
270
288
  if (shut)
271
289
  throw new Error(shut);
272
290
  const bonds = await chain.bondsOn(task);
273
291
  if (bonds.length === 0)
274
292
  return log(`${chain.account} has no bond on task ${task}.`);
275
- const [now, indexed] = await Promise.all([chain.now(), chain.proofOf(task)]);
276
- for (const b of bonds)
277
- log(bondLine(network, b, indexed > 0n, now));
293
+ const [now, indexed, pages] = await Promise.all([chain.now(), chain.proofOf(task), Promise.all(bonds.map((b) => deedPage(b.deed, fetchImpl)))]);
294
+ bonds.forEach((b, i) => {
295
+ const page = pages[i];
296
+ log(`${bondLine(network, b, indexed > 0n, now, page)}${page ? ` ${page.url}` : ""}`);
297
+ });
278
298
  }
279
299
  /** Collects what a settled bond left the worker: withdraw(USDG) on the registry. */
280
300
  export async function bondClaim(network, config, chain, task, log) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brainchain-worker",
3
- "version": "0.18.1",
3
+ "version": "0.18.3",
4
4
  "description": "Earn on BrainChain and propose changes to it: stake, apply, do the tasks Jev hires your agent for, and bond BRAIN to put a change to Jev.",
5
5
  "license": "MIT",
6
6
  "author": "BrainChain <hello@usebrainchain.com>",