clawmoney 0.5.0 → 0.7.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/commands/hire.d.ts +5 -1
- package/dist/commands/hire.js +107 -47
- package/dist/index.js +7 -3
- package/package.json +1 -1
package/dist/commands/hire.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
interface SubmitOptions {
|
|
2
2
|
url: string;
|
|
3
|
+
platform?: string;
|
|
3
4
|
text?: string;
|
|
4
5
|
}
|
|
5
6
|
interface VerifyOptions {
|
|
6
7
|
witness?: boolean;
|
|
8
|
+
relevance: string;
|
|
9
|
+
quality: string;
|
|
10
|
+
vote?: string;
|
|
7
11
|
}
|
|
8
12
|
export declare function hireSubmitCommand(taskId: string, options: SubmitOptions): Promise<void>;
|
|
9
|
-
export declare function hireVerifyCommand(
|
|
13
|
+
export declare function hireVerifyCommand(submissionId: string, options: VerifyOptions): Promise<void>;
|
|
10
14
|
export {};
|
package/dist/commands/hire.js
CHANGED
|
@@ -1,33 +1,44 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
|
-
import { apiPost } from '../utils/api.js';
|
|
3
|
+
import { apiGet, apiPost } from '../utils/api.js';
|
|
4
4
|
import { awalExec } from '../utils/awal.js';
|
|
5
5
|
import { requireConfig } from '../utils/config.js';
|
|
6
|
-
import { prompt, confirm } from '../utils/prompt.js';
|
|
7
6
|
export async function hireSubmitCommand(taskId, options) {
|
|
8
7
|
const config = requireConfig();
|
|
8
|
+
// 自动检测平台(从 task 获取)
|
|
9
|
+
let platform = options.platform;
|
|
10
|
+
if (!platform) {
|
|
11
|
+
try {
|
|
12
|
+
const taskResp = await apiGet(`/api/v1/hire/${taskId}`, config.api_key);
|
|
13
|
+
if (taskResp.ok && taskResp.data.platform) {
|
|
14
|
+
platform = taskResp.data.platform;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
catch { /* ignore */ }
|
|
18
|
+
}
|
|
19
|
+
if (!platform)
|
|
20
|
+
platform = 'twitter';
|
|
9
21
|
console.log('');
|
|
10
|
-
const spinner = ora(`Submitting proof for task ${taskId}...`).start();
|
|
22
|
+
const spinner = ora(`Submitting proof for task ${taskId.slice(0, 8)}...`).start();
|
|
11
23
|
try {
|
|
12
24
|
const body = {
|
|
25
|
+
platform,
|
|
13
26
|
proof_url: options.url,
|
|
14
27
|
};
|
|
15
28
|
if (options.text) {
|
|
16
|
-
body.
|
|
29
|
+
body.content_text = options.text;
|
|
17
30
|
}
|
|
18
31
|
const resp = await apiPost(`/api/v1/hire/${taskId}/submit`, body, config.api_key);
|
|
19
32
|
if (!resp.ok) {
|
|
20
33
|
spinner.fail('Submission failed');
|
|
21
|
-
|
|
34
|
+
const detail = typeof resp.data === 'object' ? (resp.data.detail || JSON.stringify(resp.data)) : String(resp.data);
|
|
35
|
+
console.error(chalk.red(` ${detail}`));
|
|
22
36
|
return;
|
|
23
37
|
}
|
|
24
|
-
spinner.succeed('Proof submitted
|
|
38
|
+
spinner.succeed('Proof submitted');
|
|
25
39
|
if (resp.data.id) {
|
|
26
40
|
console.log(chalk.dim(` Submission ID: ${resp.data.id}`));
|
|
27
41
|
}
|
|
28
|
-
if (resp.data.message) {
|
|
29
|
-
console.log(chalk.dim(` ${resp.data.message}`));
|
|
30
|
-
}
|
|
31
42
|
}
|
|
32
43
|
catch (err) {
|
|
33
44
|
spinner.fail('Submission failed');
|
|
@@ -35,69 +46,118 @@ export async function hireSubmitCommand(taskId, options) {
|
|
|
35
46
|
}
|
|
36
47
|
console.log('');
|
|
37
48
|
}
|
|
38
|
-
export async function hireVerifyCommand(
|
|
49
|
+
export async function hireVerifyCommand(submissionId, options) {
|
|
39
50
|
const config = requireConfig();
|
|
40
51
|
console.log('');
|
|
41
52
|
if (options.witness) {
|
|
42
|
-
//
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
53
|
+
// Get submission to extract proof_url
|
|
54
|
+
const subSpinner = ora('Fetching submission...').start();
|
|
55
|
+
let proofUrl = '';
|
|
56
|
+
try {
|
|
57
|
+
// Try to get submission details - submissionId might be used directly
|
|
58
|
+
const resp = await apiGet(`/api/v1/hire/submissions/${submissionId}`, config.api_key);
|
|
59
|
+
if (resp.ok && resp.data.proof_url) {
|
|
60
|
+
proofUrl = resp.data.proof_url;
|
|
61
|
+
subSpinner.succeed(`Proof URL: ${proofUrl}`);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
subSpinner.warn('Could not fetch submission, will need tweet ID');
|
|
65
|
+
}
|
|
47
66
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
67
|
+
catch {
|
|
68
|
+
subSpinner.warn('Could not fetch submission');
|
|
69
|
+
}
|
|
70
|
+
// Extract tweet ID
|
|
71
|
+
let tweetId = '';
|
|
72
|
+
if (proofUrl) {
|
|
73
|
+
const match = proofUrl.match(/status\/(\d+)/);
|
|
74
|
+
if (match)
|
|
75
|
+
tweetId = match[1];
|
|
76
|
+
}
|
|
77
|
+
if (!tweetId) {
|
|
78
|
+
console.error(chalk.red(' Could not extract tweet ID from proof URL'));
|
|
52
79
|
return;
|
|
53
80
|
}
|
|
54
|
-
|
|
55
|
-
const witnessSpinner = ora('
|
|
81
|
+
// Fetch witness proof via x402
|
|
82
|
+
const witnessSpinner = ora('Fetching witness proof via x402 ($0.01)...').start();
|
|
83
|
+
let witnessData;
|
|
56
84
|
try {
|
|
57
|
-
|
|
58
|
-
'x402',
|
|
59
|
-
'pay',
|
|
60
|
-
`https://witness.bnbot.ai/x/${tweetId}`,
|
|
85
|
+
witnessData = await awalExec([
|
|
86
|
+
'x402', 'pay', `https://witness.bnbot.ai/x/${tweetId}`,
|
|
61
87
|
]);
|
|
62
|
-
witnessSpinner.succeed('Witness
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
88
|
+
witnessSpinner.succeed('Witness proof obtained');
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
witnessSpinner.fail('Witness fetch failed');
|
|
92
|
+
console.error(chalk.red(err.message));
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
// Parse witness response
|
|
96
|
+
const proof = witnessData?.data?.proof || witnessData?.proof;
|
|
97
|
+
if (!proof) {
|
|
98
|
+
console.error(chalk.red(' No proof in witness response'));
|
|
99
|
+
console.log(chalk.dim(` Raw: ${JSON.stringify(witnessData).slice(0, 200)}`));
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
// Submit witness verification
|
|
103
|
+
const vote = options.vote || 'approve';
|
|
104
|
+
const relevanceScore = parseInt(options.relevance, 10);
|
|
105
|
+
const qualityScore = parseInt(options.quality, 10);
|
|
106
|
+
const verifySpinner = ora(`Submitting witness verification (${vote}, R:${relevanceScore} Q:${qualityScore})...`).start();
|
|
107
|
+
try {
|
|
108
|
+
const resp = await apiPost(`/api/v1/hire/submissions/${submissionId}/verify`, {
|
|
109
|
+
vote,
|
|
110
|
+
relevance_score: relevanceScore,
|
|
111
|
+
quality_score: qualityScore,
|
|
112
|
+
tweet_proof: {
|
|
113
|
+
payload: proof.payload,
|
|
114
|
+
signature: proof.signature,
|
|
115
|
+
signer: proof.signer,
|
|
116
|
+
timestamp: proof.timestamp,
|
|
117
|
+
},
|
|
70
118
|
}, config.api_key);
|
|
71
119
|
if (!resp.ok) {
|
|
72
|
-
|
|
73
|
-
|
|
120
|
+
verifySpinner.fail('Verification failed');
|
|
121
|
+
const detail = typeof resp.data === 'object' ? (resp.data.detail || JSON.stringify(resp.data)) : String(resp.data);
|
|
122
|
+
console.error(chalk.red(` ${detail}`));
|
|
74
123
|
}
|
|
75
124
|
else {
|
|
76
|
-
|
|
125
|
+
verifySpinner.succeed('Witness verification submitted');
|
|
126
|
+
if (resp.data.id) {
|
|
127
|
+
console.log(chalk.dim(` Verification ID: ${resp.data.id}`));
|
|
128
|
+
}
|
|
77
129
|
}
|
|
78
130
|
}
|
|
79
131
|
catch (err) {
|
|
80
|
-
|
|
132
|
+
verifySpinner.fail('Verification failed');
|
|
81
133
|
console.error(chalk.red(err.message));
|
|
82
134
|
}
|
|
83
135
|
}
|
|
84
136
|
else {
|
|
85
137
|
// Manual verification
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
const spinner = ora(
|
|
138
|
+
const vote = options.vote || 'approve';
|
|
139
|
+
const relevanceScore = parseInt(options.relevance, 10);
|
|
140
|
+
const qualityScore = parseInt(options.quality, 10);
|
|
141
|
+
const spinner = ora(`Submitting manual verification (${vote}, R:${relevanceScore} Q:${qualityScore})...`).start();
|
|
90
142
|
try {
|
|
91
|
-
const resp = await apiPost(`/api/v1/hire/${
|
|
92
|
-
|
|
93
|
-
|
|
143
|
+
const resp = await apiPost(`/api/v1/hire/submissions/${submissionId}/verify`, {
|
|
144
|
+
vote,
|
|
145
|
+
relevance_score: relevanceScore,
|
|
146
|
+
quality_score: qualityScore,
|
|
147
|
+
views: 0,
|
|
148
|
+
likes: 0,
|
|
149
|
+
comments: 0,
|
|
94
150
|
}, config.api_key);
|
|
95
151
|
if (!resp.ok) {
|
|
96
|
-
spinner.fail('Verification
|
|
97
|
-
|
|
152
|
+
spinner.fail('Verification failed');
|
|
153
|
+
const detail = typeof resp.data === 'object' ? (resp.data.detail || JSON.stringify(resp.data)) : String(resp.data);
|
|
154
|
+
console.error(chalk.red(` ${detail}`));
|
|
98
155
|
}
|
|
99
156
|
else {
|
|
100
|
-
spinner.succeed(
|
|
157
|
+
spinner.succeed('Manual verification submitted');
|
|
158
|
+
if (resp.data.id) {
|
|
159
|
+
console.log(chalk.dim(` Verification ID: ${resp.data.id}`));
|
|
160
|
+
}
|
|
101
161
|
}
|
|
102
162
|
}
|
|
103
163
|
catch (err) {
|
package/dist/index.js
CHANGED
|
@@ -45,6 +45,7 @@ hire
|
|
|
45
45
|
.command('submit <task-id>')
|
|
46
46
|
.description('Submit a proof for a hire task')
|
|
47
47
|
.requiredOption('-u, --url <url>', 'Proof URL (tweet, post, etc.)')
|
|
48
|
+
.option('-p, --platform <platform>', 'Platform (auto-detected from task)')
|
|
48
49
|
.option('--text <content>', 'Optional text content')
|
|
49
50
|
.action(async (taskId, options) => {
|
|
50
51
|
try {
|
|
@@ -56,9 +57,12 @@ hire
|
|
|
56
57
|
}
|
|
57
58
|
});
|
|
58
59
|
hire
|
|
59
|
-
.command('verify <
|
|
60
|
-
.description('Verify a hire
|
|
61
|
-
.option('-w, --witness', 'Use x402 witness verification')
|
|
60
|
+
.command('verify <submission-id>')
|
|
61
|
+
.description('Verify a hire submission')
|
|
62
|
+
.option('-w, --witness', 'Use x402 witness verification ($0.01)')
|
|
63
|
+
.requiredOption('-r, --relevance <score>', 'Relevance score (1-10)')
|
|
64
|
+
.requiredOption('-q, --quality <score>', 'Quality score (1-10)')
|
|
65
|
+
.option('-v, --vote <vote>', 'Vote: approve or reject', 'approve')
|
|
62
66
|
.action(async (taskId, options) => {
|
|
63
67
|
try {
|
|
64
68
|
await hireVerifyCommand(taskId, options);
|