@ixo/asks-mcp 2.0.0-dev.6 → 2.0.0

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/asks-mcp.mjs +41 -35
  2. package/package.json +1 -1
package/dist/asks-mcp.mjs CHANGED
@@ -38786,9 +38786,9 @@ function nLength(n, nBitLength) {
38786
38786
  const nByteLength = Math.ceil(_nBitLength / 8);
38787
38787
  return { nBitLength: _nBitLength, nByteLength };
38788
38788
  }
38789
- function Field(ORDER2, opts = {}) {
38789
+ function Field(ORDER3, opts = {}) {
38790
38790
  Object.freeze(_Field.prototype);
38791
- return new _Field(ORDER2, opts);
38791
+ return new _Field(ORDER3, opts);
38792
38792
  }
38793
38793
  function FpSqrtEven(Fp2, elm) {
38794
38794
  validateField(Fp2);
@@ -38867,9 +38867,9 @@ var init_modular = __esm({
38867
38867
  ONE = _1n3;
38868
38868
  _lengths;
38869
38869
  _mod;
38870
- constructor(ORDER2, opts = {}) {
38871
- if (ORDER2 <= _1n3)
38872
- throw new Error("invalid field: expected ORDER > 1, got " + ORDER2);
38870
+ constructor(ORDER3, opts = {}) {
38871
+ if (ORDER3 <= _1n3)
38872
+ throw new Error("invalid field: expected ORDER > 1, got " + ORDER3);
38873
38873
  let _nbitLength = void 0;
38874
38874
  this.isLE = false;
38875
38875
  if (opts != null && typeof opts === "object") {
@@ -38884,10 +38884,10 @@ var init_modular = __esm({
38884
38884
  if (typeof opts.modFromBytes === "boolean")
38885
38885
  this._mod = opts.modFromBytes;
38886
38886
  }
38887
- const { nBitLength, nByteLength } = nLength(ORDER2, _nbitLength);
38887
+ const { nBitLength, nByteLength } = nLength(ORDER3, _nbitLength);
38888
38888
  if (nByteLength > 2048)
38889
38889
  throw new Error("invalid field: expected ORDER of <= 2048 bytes");
38890
- this.ORDER = ORDER2;
38890
+ this.ORDER = ORDER3;
38891
38891
  this.BITS = nBitLength;
38892
38892
  this.BYTES = nByteLength;
38893
38893
  Object.freeze(this);
@@ -38961,7 +38961,7 @@ var init_modular = __esm({
38961
38961
  }
38962
38962
  fromBytes(bytes3, skipValidation = false) {
38963
38963
  abytes5(bytes3);
38964
- const { _lengths: allowedLengths, BYTES, isLE: isLE3, ORDER: ORDER2, _mod: modFromBytes } = this;
38964
+ const { _lengths: allowedLengths, BYTES, isLE: isLE3, ORDER: ORDER3, _mod: modFromBytes } = this;
38965
38965
  if (allowedLengths) {
38966
38966
  if (bytes3.length < 1 || !allowedLengths.includes(bytes3.length) || bytes3.length > BYTES) {
38967
38967
  throw new Error("Field.fromBytes: expected " + allowedLengths + " bytes, got " + bytes3.length);
@@ -38974,7 +38974,7 @@ var init_modular = __esm({
38974
38974
  throw new Error("Field.fromBytes: expected " + BYTES + " bytes, got " + bytes3.length);
38975
38975
  let scalar = isLE3 ? bytesToNumberLE2(bytes3) : bytesToNumberBE(bytes3);
38976
38976
  if (modFromBytes)
38977
- scalar = mod2(scalar, ORDER2);
38977
+ scalar = mod2(scalar, ORDER3);
38978
38978
  if (!skipValidation) {
38979
38979
  if (!this.isValid(scalar))
38980
38980
  throw new Error("invalid field element: outside of range 0..ORDER");
@@ -266886,6 +266886,11 @@ __export(cashout_exports, {
266886
266886
  cashOutStatus: () => cashOutStatus,
266887
266887
  identityLine: () => identityLine
266888
266888
  });
266889
+ function whyOff(one) {
266890
+ if (one.enabled === false) return one.reason === "not_in_country" ? "not offered in your country yet" : one.reason === "coming_soon" ? "coming soon" : "busy right now, try later";
266891
+ if (one.provider === "yellowcard-worker" || one.method.startsWith("yellowcard")) return "coming soon";
266892
+ return null;
266893
+ }
266889
266894
  async function call2(deps, path, body) {
266890
266895
  try {
266891
266896
  const response = await deps.fetch(`${deps.site.replace(/\/+$/, "")}${path}`, {
@@ -266926,38 +266931,38 @@ async function cashOut(deps, input) {
266926
266931
  if (!country || !/^[A-Z]{2}$/.test(country)) return [`You have $${available.toFixed(2)} to cash out.`, kycLine, 'Which country are you in? (Ask the person; then call cash_out with country, like "NG" or "DE".)'].filter(Boolean).join("\n");
266927
266932
  const info = await call2(deps, `/api/cashout/info?country=${country}`);
266928
266933
  if (info.status !== 200) return said3(info);
266929
- const methods = info.body.methods ?? [];
266934
+ const methods = (info.body.methods ?? []).filter((one) => WAYS[one.method]).sort((a, b) => ORDER2.indexOf(a.method) - ORDER2.indexOf(b.method));
266930
266935
  const fee = info.body.fee;
266931
- if (!methods.length) return `There's no way to cash out in ${country} yet.`;
266932
- const chosen2 = methods.find((one) => one.method === input.method);
266936
+ if (!methods.some((one) => !whyOff(one))) return `We can't send money to ${country} yet.`;
266937
+ const chosen2 = methods.find((one) => one.method === input.method && !whyOff(one));
266933
266938
  if (!chosen2)
266934
266939
  return [
266935
266940
  `You have $${available.toFixed(2)} to cash out. Ways to get paid in ${country}:`,
266936
- ...methods.map((one) => `- ${WAYS[one.method] ?? one.method} (method "${one.method}"): $${one.minUsd} to $${one.maxUsd}`),
266941
+ ...methods.map((one) => `- ${WAYS[one.method]} (method "${one.method}"): ${whyOff(one) ?? `$${one.minUsd ?? "0.00"}${one.maxUsd ? ` to $${one.maxUsd}` : ""}`}`),
266937
266942
  `Fee: ${fee?.bps ? `${fee.bps / 100}%` : "none"}${fee?.minUsd && Number(fee.minUsd) > 0 ? `, at least $${fee.minUsd}` : ""}.`,
266938
266943
  kycLine,
266939
266944
  "(Ask which way and how much; then call cash_out with method and amount_usd.)"
266940
266945
  ].filter(Boolean).join("\n");
266941
266946
  const amount3 = input.amount_usd?.trim().replace(/^\$/, "");
266942
- if (!amount3 || !/^\d+(\.\d{1,2})?$/.test(amount3)) return `How much do you want to cash out? You have $${available.toFixed(2)}; this way takes $${chosen2.minUsd} to $${chosen2.maxUsd}. (Then call cash_out with amount_usd, like "25".)`;
266947
+ if (!amount3 || !/^\d+(\.\d{1,2})?$/.test(amount3)) return `How much do you want to cash out? You have $${available.toFixed(2)}; this way takes $${chosen2.minUsd ?? "0.00"}${chosen2.maxUsd ? ` to $${chosen2.maxUsd}` : ""}. (Then call cash_out with amount_usd, like "25".)`;
266943
266948
  if (Number(amount3) > available) return `You have $${available.toFixed(2)} to cash out, less than $${amount3}. Pick a smaller amount.`;
266944
- if (Number(amount3) < Number(chosen2.minUsd)) return `The smallest you can cash out this way is $${chosen2.minUsd}.`;
266945
- if (Number(amount3) > Number(chosen2.maxUsd)) return `The largest you can cash out this way is $${chosen2.maxUsd}.`;
266949
+ if (chosen2.minUsd && Number(amount3) < Number(chosen2.minUsd)) return `The smallest you can cash out this way is $${chosen2.minUsd}.`;
266950
+ if (chosen2.maxUsd && Number(amount3) > Number(chosen2.maxUsd)) return `The largest you can cash out this way is $${chosen2.maxUsd}.`;
266946
266951
  const to = input.to?.trim();
266947
266952
  if (chosen2.fields.includes("address") && !(to && BASE_ADDRESS.test(to))) return "Which Base account should receive it? (Its address starts with 0x; then call cash_out with to.)";
266948
266953
  const quote = await signedCall(deps, "quote", { method: chosen2.method, country, amountUsd: amount3 });
266949
266954
  if (quote.status !== 201) return said3(quote);
266950
266955
  const q = quote.body;
266951
- const receive = `You'll receive $${q.receive?.amount ?? q.amountUsd}${q.receive?.currency && q.receive.currency !== "USD" ? ` in ${q.receive.currency}` : ""} (fee $${q.feeUsd ?? "0.00"}).`;
266956
+ const receive = `You'll receive $${q.receive?.amount ?? q.amountUsd} (fee $${q.feeUsd ?? "0.00"}).`;
266952
266957
  const named = chosen2.fields.includes("accountHolder") ? NAME_LINE : "";
266953
- if (!input.confirm) return [`Cash out $${q.amountUsd} by ${WAYS[chosen2.method] ?? chosen2.method}${to ? ` to ${to}` : ""}.`, receive, named, kycLine, "Nothing is sent yet. To go ahead, call cash_out again with the same answers and confirm: true."].filter(Boolean).join("\n");
266958
+ if (!input.confirm) return [`Cash out $${q.amountUsd}: ${WAYS[chosen2.method]}${to ? `, to ${to}` : ""}.`, receive, named, kycLine, "Nothing is sent yet. To go ahead, call cash_out again with the same answers and confirm: true."].filter(Boolean).join("\n");
266954
266959
  const link5 = new URL(`${deps.site.replace(/\/+$/, "")}/me/cash-out`);
266955
266960
  link5.searchParams.set("quote", String(q.quoteId));
266956
266961
  link5.searchParams.set("method", chosen2.method);
266957
266962
  link5.searchParams.set("amount", amount3);
266958
266963
  link5.searchParams.set("country", country);
266959
266964
  if (to) link5.searchParams.set("to", to);
266960
- return [receive, named, `Open this and confirm with one tap: ${link5.toString()}`, "Your money leaves only when you confirm there. I signed nothing. (Later, cash_out_status with the id that page shows says where it stands.)"].filter(Boolean).join("\n");
266965
+ return [receive, named, `Open this and tap Confirm: ${link5.toString()}`, "Your money leaves only when you confirm there. I sent nothing. (Later, cash_out_status with the id that page shows says where it stands.)"].filter(Boolean).join("\n");
266961
266966
  }
266962
266967
  async function cashOutStatus(deps, id) {
266963
266968
  const answer = await signedCall(deps, "status", { id });
@@ -266969,12 +266974,12 @@ async function cashOutStatus(deps, id) {
266969
266974
  switch (lapsed ? "expired" : v.state) {
266970
266975
  case "open":
266971
266976
  case "signing":
266972
- return `Not confirmed yet: open the confirm link and tap confirm (${money2}).`;
266977
+ return `Not confirmed yet: open the link and tap Confirm (${money2}).`;
266973
266978
  case "sent":
266974
- return "Confirmed. The payout is starting.";
266979
+ return "Confirmed. It's on its way.";
266975
266980
  case "expired":
266976
266981
  case "failed":
266977
- return "This cash-out expired before it was confirmed. Nothing was taken. Start a new one with cash_out.";
266982
+ return "This took too long, so it was stopped. Nothing was taken. Start a new one with cash_out.";
266978
266983
  case "converting":
266979
266984
  case "taking":
266980
266985
  case "paying":
@@ -266982,31 +266987,32 @@ async function cashOutStatus(deps, id) {
266982
266987
  case "paid":
266983
266988
  return `Paid: ${money2}.`;
266984
266989
  case "needs_attention":
266985
- return `Your payout didn't go through: ${v.reason ?? "the payout failed"}. Check your details or pick another way: ${v.fixUrl ?? ""}
266986
- ${NAME_LINE}`;
266990
+ return v.fixUrl ? `Something needs fixing: the money didn't reach you. Check your details or pick another way here: ${v.fixUrl}
266991
+ ${NAME_LINE}` : "Something needs fixing, and we're looking into it. Nothing to do on your side.";
266987
266992
  case "not_converted":
266988
266993
  case "cancelled":
266989
- return "This cash-out didn't go through, and nothing was taken.";
266994
+ return "It didn't go through, and nothing was taken.";
266990
266995
  case "refunded":
266991
- return "Your money was sent back to you.";
266996
+ return "Your money is back in your account.";
266992
266997
  default:
266993
- return `State: ${v.state ?? "unknown"}.`;
266998
+ return "We're still checking where it stands. Ask again in a minute.";
266994
266999
  }
266995
267000
  }
266996
- var WAYS, BASE_ADDRESS, NAME_LINE, said3;
267001
+ var WAYS, ORDER2, BASE_ADDRESS, NAME_LINE, said3;
266997
267002
  var init_cashout = __esm({
266998
267003
  "src/cashout.ts"() {
266999
267004
  "use strict";
267000
267005
  init_accountProof();
267001
267006
  init_inviteProof();
267002
267007
  WAYS = {
267003
- usdc_base: "Digital dollars to your own Base account (any country)",
267004
- stripe_bank: "Bank account, through Stripe",
267005
- yellowcard_bank: "Bank account, through Yellow Card",
267006
- yellowcard_momo: "Mobile money, through Yellow Card"
267008
+ stripe_bank: "To your bank account (through Stripe)",
267009
+ yellowcard_bank: "To your bank account (through Yellow Card)",
267010
+ yellowcard_momo: "To your mobile money (M-PESA, MTN and others)",
267011
+ usdc_base: "Digital dollars (USDC), to your own Base account (its address starts with 0x)"
267007
267012
  };
267013
+ ORDER2 = Object.keys(WAYS);
267008
267014
  BASE_ADDRESS = /^0x[0-9a-fA-F]{40}$/;
267009
- NAME_LINE = "The payout account name must match the name on your ID.";
267015
+ NAME_LINE = "The name on the account must match the name on your ID.";
267010
267016
  said3 = (answer) => answer.status === 503 && answer.body.code === "not-open" ? "Cash-out isn't open on this network yet." : String(answer.body.error ?? `Cash-out refused this (${answer.status}).`);
267011
267017
  }
267012
267018
  });
@@ -292374,7 +292380,7 @@ import { randomBytes as randomBytes7 } from "node:crypto";
292374
292380
  // package.json
292375
292381
  var package_default = {
292376
292382
  name: "@ixo/asks-mcp",
292377
- version: "2.0.0-dev.6",
292383
+ version: "2.0.0",
292378
292384
  description: "The Openhands Network MCP server: read the board, answer asks, post work and get paid on the ixo chain, with a key of its own on your machine.",
292379
292385
  license: "Apache-2.0",
292380
292386
  repository: {
@@ -292598,7 +292604,7 @@ var TOOLS = {
292598
292604
  },
292599
292605
  cash_out: {
292600
292606
  title: "Cash out your earnings",
292601
- description: `Turn what the person earned into money: digital dollars to your own Base account, or a bank account where offered. One step per call: it reads what they have available, their LinkedIn and identity check, then asks the country, the way to get paid, the amount and (for a Base account) the address, and shows the quote in plain words ("You'll receive $X (fee $0)"). With confirm: true it gives ONE link: the person opens it and confirms with one tap; that page checks their identity and they sign there. Limits and fees come from IXO's cash-out service, never from here. No LinkedIn: say connect_linkedin first. Signs no money and holds no key of theirs.`,
292607
+ description: `Turn what the person earned into money: to their bank account, their mobile money, or "Digital dollars (USDC)" to their own Base account, where offered. Speak plainly to the person: no technical words. One step per call: it reads what they have available, their LinkedIn and identity check, then asks the country, the way to get paid (every way is listed; the ones they can't pick say why), the amount and (for digital dollars) the 0x address, and shows "You'll receive $X (fee $0)". With confirm: true it gives ONE link: the person opens it and taps Confirm there, where their identity is checked and they confirm in their sign-in app. Limits and fees come from IXO's cash-out service, never from here. No LinkedIn: say connect_linkedin first. Signs no money and holds no key of theirs.`,
292602
292608
  spends: false,
292603
292609
  hosted: false,
292604
292610
  annotations: acts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ixo/asks-mcp",
3
- "version": "2.0.0-dev.6",
3
+ "version": "2.0.0",
4
4
  "description": "The Openhands Network MCP server: read the board, answer asks, post work and get paid on the ixo chain, with a key of its own on your machine.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {