@ixo/asks-mcp 2.0.0-dev.5 → 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.
- package/dist/asks-mcp.mjs +55 -40
- 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(
|
|
38789
|
+
function Field(ORDER3, opts = {}) {
|
|
38790
38790
|
Object.freeze(_Field.prototype);
|
|
38791
|
-
return new _Field(
|
|
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(
|
|
38871
|
-
if (
|
|
38872
|
-
throw new Error("invalid field: expected ORDER > 1, got " +
|
|
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(
|
|
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 =
|
|
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:
|
|
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,
|
|
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");
|
|
@@ -264720,7 +264720,7 @@ var init_inviteMessages = __esm({
|
|
|
264720
264720
|
return rest;
|
|
264721
264721
|
};
|
|
264722
264722
|
linkedinMessage = (act, signer2, now3 = Date.now(), digest2 = "") => `linkedin:${act}:${signer2}:${now3}:${digest2}`;
|
|
264723
|
-
CASHOUT_ACTS = ["quote", "draft", "status"];
|
|
264723
|
+
CASHOUT_ACTS = ["quote", "draft", "status", "kyc"];
|
|
264724
264724
|
cashoutMessage = (act, signer2, now3 = Date.now(), digest2 = "") => `cashout:${act}:${signer2}:${now3}:${digest2}`;
|
|
264725
264725
|
ROOM_ACTS = ["mine", "read", "send", "bring", "export"];
|
|
264726
264726
|
roomBody = (body) => {
|
|
@@ -266883,8 +266883,14 @@ var init_takeBack = __esm({
|
|
|
266883
266883
|
var cashout_exports = {};
|
|
266884
266884
|
__export(cashout_exports, {
|
|
266885
266885
|
cashOut: () => cashOut,
|
|
266886
|
-
cashOutStatus: () => cashOutStatus
|
|
266886
|
+
cashOutStatus: () => cashOutStatus,
|
|
266887
|
+
identityLine: () => identityLine
|
|
266887
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
|
+
}
|
|
266888
266894
|
async function call2(deps, path, body) {
|
|
266889
266895
|
try {
|
|
266890
266896
|
const response = await deps.fetch(`${deps.site.replace(/\/+$/, "")}${path}`, {
|
|
@@ -266903,52 +266909,60 @@ async function signedCall(deps, act, fields) {
|
|
|
266903
266909
|
const message = await cashoutWords(act, deps.signer.address, full);
|
|
266904
266910
|
return call2(deps, `/api/cashout/${act}`, { address: deps.signer.address, ...full, proof: { kind: "adr36", message, ...await signWords(deps.signer.mnemonic, message) } });
|
|
266905
266911
|
}
|
|
266912
|
+
async function identityLine(deps) {
|
|
266913
|
+
const answer = await signedCall(deps, "kyc", {});
|
|
266914
|
+
const status = answer.status === 200 ? answer.body.status : "unknown";
|
|
266915
|
+
if (status === "verified") return "Your identity check is done.";
|
|
266916
|
+
if (status === "in_review") return "Your identity check is being reviewed.";
|
|
266917
|
+
const info = await call2(deps, "/api/cashout/info");
|
|
266918
|
+
const kycUrl = typeof info.body.kycUrl === "string" ? info.body.kycUrl : `${deps.site.replace(/\/+$/, "")}/me/identity`;
|
|
266919
|
+
return `Do your identity check first: ${kycUrl}`;
|
|
266920
|
+
}
|
|
266906
266921
|
async function cashOut(deps, input) {
|
|
266907
266922
|
const person = deps.signer.principal ?? deps.signer.address;
|
|
266908
|
-
const [ready, payBase] = await Promise.all([signedCall(deps, "status", {}), deps.payBase(person)]);
|
|
266923
|
+
const [ready, payBase, kycLine] = await Promise.all([signedCall(deps, "status", {}), deps.payBase(person), identityLine(deps)]);
|
|
266909
266924
|
if (ready.status !== 200) return said3(ready);
|
|
266910
266925
|
const kyc = ready.body.kyc;
|
|
266911
266926
|
if (!ready.body.linkedin) return "Cash-out needs your LinkedIn connected first. Next: connect_linkedin (about a minute), then cash_out again.";
|
|
266912
266927
|
const available = payBase / 1e6;
|
|
266913
266928
|
if (available <= 0) return "You have nothing to cash out yet.";
|
|
266914
|
-
|
|
266915
|
-
if (kyc?.status === "expired") return kycLine;
|
|
266929
|
+
if (kyc?.status === "expired") return `Your identity check has expired. Renew it first: ${deps.site.replace(/\/+$/, "")}/me/identity`;
|
|
266916
266930
|
const country = input.country?.trim().toUpperCase();
|
|
266917
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");
|
|
266918
266932
|
const info = await call2(deps, `/api/cashout/info?country=${country}`);
|
|
266919
266933
|
if (info.status !== 200) return said3(info);
|
|
266920
|
-
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));
|
|
266921
266935
|
const fee = info.body.fee;
|
|
266922
|
-
if (!methods.
|
|
266923
|
-
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));
|
|
266924
266938
|
if (!chosen2)
|
|
266925
266939
|
return [
|
|
266926
266940
|
`You have $${available.toFixed(2)} to cash out. Ways to get paid in ${country}:`,
|
|
266927
|
-
...methods.map((one) => `- ${WAYS[one.method]
|
|
266941
|
+
...methods.map((one) => `- ${WAYS[one.method]} (method "${one.method}"): ${whyOff(one) ?? `$${one.minUsd ?? "0.00"}${one.maxUsd ? ` to $${one.maxUsd}` : ""}`}`),
|
|
266928
266942
|
`Fee: ${fee?.bps ? `${fee.bps / 100}%` : "none"}${fee?.minUsd && Number(fee.minUsd) > 0 ? `, at least $${fee.minUsd}` : ""}.`,
|
|
266929
266943
|
kycLine,
|
|
266930
266944
|
"(Ask which way and how much; then call cash_out with method and amount_usd.)"
|
|
266931
266945
|
].filter(Boolean).join("\n");
|
|
266932
266946
|
const amount3 = input.amount_usd?.trim().replace(/^\$/, "");
|
|
266933
|
-
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".)`;
|
|
266934
266948
|
if (Number(amount3) > available) return `You have $${available.toFixed(2)} to cash out, less than $${amount3}. Pick a smaller amount.`;
|
|
266935
|
-
if (Number(amount3) < Number(chosen2.minUsd)) return `The smallest you can cash out this way is $${chosen2.minUsd}.`;
|
|
266936
|
-
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}.`;
|
|
266937
266951
|
const to = input.to?.trim();
|
|
266938
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.)";
|
|
266939
266953
|
const quote = await signedCall(deps, "quote", { method: chosen2.method, country, amountUsd: amount3 });
|
|
266940
266954
|
if (quote.status !== 201) return said3(quote);
|
|
266941
266955
|
const q = quote.body;
|
|
266942
|
-
const receive = `You'll receive $${q.receive?.amount ?? q.amountUsd}
|
|
266956
|
+
const receive = `You'll receive $${q.receive?.amount ?? q.amountUsd} (fee $${q.feeUsd ?? "0.00"}).`;
|
|
266943
266957
|
const named = chosen2.fields.includes("accountHolder") ? NAME_LINE : "";
|
|
266944
|
-
if (!input.confirm) return [`Cash out $${q.amountUsd}
|
|
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");
|
|
266945
266959
|
const link5 = new URL(`${deps.site.replace(/\/+$/, "")}/me/cash-out`);
|
|
266946
266960
|
link5.searchParams.set("quote", String(q.quoteId));
|
|
266947
266961
|
link5.searchParams.set("method", chosen2.method);
|
|
266948
266962
|
link5.searchParams.set("amount", amount3);
|
|
266949
266963
|
link5.searchParams.set("country", country);
|
|
266950
266964
|
if (to) link5.searchParams.set("to", to);
|
|
266951
|
-
return [receive, named, `Open this and
|
|
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");
|
|
266952
266966
|
}
|
|
266953
266967
|
async function cashOutStatus(deps, id) {
|
|
266954
266968
|
const answer = await signedCall(deps, "status", { id });
|
|
@@ -266960,12 +266974,12 @@ async function cashOutStatus(deps, id) {
|
|
|
266960
266974
|
switch (lapsed ? "expired" : v.state) {
|
|
266961
266975
|
case "open":
|
|
266962
266976
|
case "signing":
|
|
266963
|
-
return `Not confirmed yet: open the
|
|
266977
|
+
return `Not confirmed yet: open the link and tap Confirm (${money2}).`;
|
|
266964
266978
|
case "sent":
|
|
266965
|
-
return "Confirmed.
|
|
266979
|
+
return "Confirmed. It's on its way.";
|
|
266966
266980
|
case "expired":
|
|
266967
266981
|
case "failed":
|
|
266968
|
-
return "This
|
|
266982
|
+
return "This took too long, so it was stopped. Nothing was taken. Start a new one with cash_out.";
|
|
266969
266983
|
case "converting":
|
|
266970
266984
|
case "taking":
|
|
266971
266985
|
case "paying":
|
|
@@ -266973,31 +266987,32 @@ async function cashOutStatus(deps, id) {
|
|
|
266973
266987
|
case "paid":
|
|
266974
266988
|
return `Paid: ${money2}.`;
|
|
266975
266989
|
case "needs_attention":
|
|
266976
|
-
return
|
|
266977
|
-
${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.";
|
|
266978
266992
|
case "not_converted":
|
|
266979
266993
|
case "cancelled":
|
|
266980
|
-
return "
|
|
266994
|
+
return "It didn't go through, and nothing was taken.";
|
|
266981
266995
|
case "refunded":
|
|
266982
|
-
return "Your money
|
|
266996
|
+
return "Your money is back in your account.";
|
|
266983
266997
|
default:
|
|
266984
|
-
return
|
|
266998
|
+
return "We're still checking where it stands. Ask again in a minute.";
|
|
266985
266999
|
}
|
|
266986
267000
|
}
|
|
266987
|
-
var WAYS, BASE_ADDRESS, NAME_LINE, said3;
|
|
267001
|
+
var WAYS, ORDER2, BASE_ADDRESS, NAME_LINE, said3;
|
|
266988
267002
|
var init_cashout = __esm({
|
|
266989
267003
|
"src/cashout.ts"() {
|
|
266990
267004
|
"use strict";
|
|
266991
267005
|
init_accountProof();
|
|
266992
267006
|
init_inviteProof();
|
|
266993
267007
|
WAYS = {
|
|
266994
|
-
|
|
266995
|
-
|
|
266996
|
-
|
|
266997
|
-
|
|
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)"
|
|
266998
267012
|
};
|
|
267013
|
+
ORDER2 = Object.keys(WAYS);
|
|
266999
267014
|
BASE_ADDRESS = /^0x[0-9a-fA-F]{40}$/;
|
|
267000
|
-
NAME_LINE = "The
|
|
267015
|
+
NAME_LINE = "The name on the account must match the name on your ID.";
|
|
267001
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}).`);
|
|
267002
267017
|
}
|
|
267003
267018
|
});
|
|
@@ -292365,7 +292380,7 @@ import { randomBytes as randomBytes7 } from "node:crypto";
|
|
|
292365
292380
|
// package.json
|
|
292366
292381
|
var package_default = {
|
|
292367
292382
|
name: "@ixo/asks-mcp",
|
|
292368
|
-
version: "2.0.0
|
|
292383
|
+
version: "2.0.0",
|
|
292369
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.",
|
|
292370
292385
|
license: "Apache-2.0",
|
|
292371
292386
|
repository: {
|
|
@@ -292589,7 +292604,7 @@ var TOOLS = {
|
|
|
292589
292604
|
},
|
|
292590
292605
|
cash_out: {
|
|
292591
292606
|
title: "Cash out your earnings",
|
|
292592
|
-
description: `Turn what the person earned into money:
|
|
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.`,
|
|
292593
292608
|
spends: false,
|
|
292594
292609
|
hosted: false,
|
|
292595
292610
|
annotations: acts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ixo/asks-mcp",
|
|
3
|
-
"version": "2.0.0
|
|
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": {
|