@relai-fi/x402 0.5.39 → 0.6.0-rc.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/README.md +380 -21
- package/dist/index.cjs +75 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -1
- package/dist/plugins.cjs +21467 -45
- package/dist/plugins.cjs.map +1 -1
- package/dist/plugins.d.cts +2 -1
- package/dist/plugins.d.ts +2 -1
- package/dist/plugins.js +21477 -33
- package/dist/plugins.js.map +1 -1
- package/dist/relay-feedback.cjs +86 -0
- package/dist/relay-feedback.cjs.map +1 -0
- package/dist/relay-feedback.d.cts +63 -0
- package/dist/relay-feedback.d.ts +63 -0
- package/dist/relay-feedback.js +61 -0
- package/dist/relay-feedback.js.map +1 -0
- package/dist/server-Dr3JOA0-.d.ts +713 -0
- package/dist/server-t9nKvoKl.d.cts +713 -0
- package/dist/server.cjs +15 -0
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +2 -1
- package/dist/server.d.ts +2 -1
- package/dist/server.js +15 -0
- package/dist/server.js.map +1 -1
- package/package.json +10 -1
- package/dist/server-CaSmhDnd.d.ts +0 -312
- package/dist/server-CyfEHW9D.d.cts +0 -312
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/relay-feedback.ts
|
|
21
|
+
var relay_feedback_exports = {};
|
|
22
|
+
__export(relay_feedback_exports, {
|
|
23
|
+
submitRelayFeedback: () => submitRelayFeedback
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(relay_feedback_exports);
|
|
26
|
+
var import_ethers = require("ethers");
|
|
27
|
+
var RELAY_FEEDBACK_REPUTATION_ABI = [
|
|
28
|
+
"function giveFeedback(uint256 agentId, int128 value, uint8 valueDecimals, string tag1, string tag2, string endpoint, string feedbackURI, bytes32 feedbackHash) external"
|
|
29
|
+
];
|
|
30
|
+
function submitRelayFeedback(config) {
|
|
31
|
+
const agentId = String(config.agentId);
|
|
32
|
+
const endpoint = config.endpoint ?? "";
|
|
33
|
+
const responseTimeMs = config.responseTimeMs ?? 0;
|
|
34
|
+
const privateKey = config.feedbackWalletPrivateKey ?? (typeof process !== "undefined" ? process.env?.FEEDBACK_WALLET_PRIVATE_KEY ?? process.env?.ERC8004_FEEDBACK_WALLET_PRIVATE_KEY : void 0);
|
|
35
|
+
const reputationAddress = config.reputationRegistryAddress ?? (typeof process !== "undefined" ? process.env?.ERC8004_REPUTATION_REGISTRY : void 0);
|
|
36
|
+
const rpcUrl = config.rpcUrl ?? (typeof process !== "undefined" ? process.env?.ERC8004_RPC_URL : void 0) ?? "https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha";
|
|
37
|
+
if (!privateKey || !reputationAddress) {
|
|
38
|
+
console.warn("[relai:submitRelayFeedback] FEEDBACK_WALLET_PRIVATE_KEY or ERC8004_REPUTATION_REGISTRY not set \u2014 skipping");
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const provider = new import_ethers.ethers.JsonRpcProvider(rpcUrl);
|
|
42
|
+
const signer = new import_ethers.ethers.Wallet(privateKey, provider);
|
|
43
|
+
const reputation = new import_ethers.ethers.Contract(reputationAddress, RELAY_FEEDBACK_REPUTATION_ABI, signer);
|
|
44
|
+
const id = BigInt(agentId);
|
|
45
|
+
(async () => {
|
|
46
|
+
const successValue = config.success ? 10000n : 0n;
|
|
47
|
+
try {
|
|
48
|
+
const srTx = await reputation.giveFeedback(
|
|
49
|
+
id,
|
|
50
|
+
successValue,
|
|
51
|
+
2,
|
|
52
|
+
"successRate",
|
|
53
|
+
"",
|
|
54
|
+
endpoint,
|
|
55
|
+
"",
|
|
56
|
+
import_ethers.ethers.ZeroHash
|
|
57
|
+
);
|
|
58
|
+
await srTx.wait();
|
|
59
|
+
console.log(`[relai:submitRelayFeedback] successRate confirmed agentId=${agentId} success=${config.success}`);
|
|
60
|
+
} catch (err) {
|
|
61
|
+
console.warn(`[relai:submitRelayFeedback] successRate failed (non-fatal): ${err?.message}`);
|
|
62
|
+
}
|
|
63
|
+
if (responseTimeMs > 0) {
|
|
64
|
+
try {
|
|
65
|
+
const rtTx = await reputation.giveFeedback(
|
|
66
|
+
id,
|
|
67
|
+
BigInt(Math.max(0, Math.round(responseTimeMs))),
|
|
68
|
+
0,
|
|
69
|
+
"responseTime",
|
|
70
|
+
"",
|
|
71
|
+
endpoint,
|
|
72
|
+
"",
|
|
73
|
+
import_ethers.ethers.ZeroHash
|
|
74
|
+
);
|
|
75
|
+
console.log(`[relai:submitRelayFeedback] responseTime sent agentId=${agentId} ms=${responseTimeMs} tx=${rtTx.hash}`);
|
|
76
|
+
} catch (err) {
|
|
77
|
+
console.warn(`[relai:submitRelayFeedback] responseTime failed (non-fatal): ${err?.message}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
})();
|
|
81
|
+
}
|
|
82
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
83
|
+
0 && (module.exports = {
|
|
84
|
+
submitRelayFeedback
|
|
85
|
+
});
|
|
86
|
+
//# sourceMappingURL=relay-feedback.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/relay-feedback.ts"],"sourcesContent":["// src/relay-feedback.ts\n// Standalone utility for submitting ERC-8004 feedback about third-party APIs.\n// Not a plugin — call directly from your relay/aggregator application code.\n\nimport { ethers } from 'ethers';\n\nexport interface RelayFeedbackConfig {\n /**\n * ERC-8004 agentId (NFT tokenId) of the **target API** you are calling.\n */\n agentId: string | number;\n /**\n * Whether the API call succeeded.\n */\n success: boolean;\n /**\n * Elapsed milliseconds for the API call.\n */\n responseTimeMs?: number;\n /**\n * Endpoint path of the called API (e.g. '/v1/data').\n */\n endpoint?: string;\n /**\n * Private key of the **relay/third-party** wallet that signs feedback.\n * MUST be different from the API owner's wallet — ReputationRegistry\n * may restrict self-feedback. Wallet needs CREDIT tokens on SKALE Base.\n * Default: process.env.FEEDBACK_WALLET_PRIVATE_KEY\n */\n feedbackWalletPrivateKey?: string;\n /**\n * SKALE Base Sepolia RPC URL.\n * Default: process.env.ERC8004_RPC_URL or SKALE Base Sepolia public RPC.\n */\n rpcUrl?: string;\n /**\n * ERC-8004 ReputationRegistry contract address.\n * Default: process.env.ERC8004_REPUTATION_REGISTRY\n */\n reputationRegistryAddress?: string;\n}\n\nconst RELAY_FEEDBACK_REPUTATION_ABI = [\n 'function giveFeedback(uint256 agentId, int128 value, uint8 valueDecimals, string tag1, string tag2, string endpoint, string feedbackURI, bytes32 feedbackHash) external',\n];\n\n/**\n * Submit ERC-8004 on-chain feedback about a **third-party API** you called.\n *\n * Call this fire-and-forget from your relay/aggregator after every external API call.\n * Uses a separate relay wallet (not the API owner's key) to avoid self-feedback restrictions.\n *\n * Records:\n * - `successRate`: 10000 (= 100%) on success, 0 on failure — 2 decimal places\n * - `responseTime`: elapsed milliseconds\n *\n * @example\n * ```typescript\n * import { submitRelayFeedback } from '@relai-fi/x402/relay-feedback';\n *\n * // after calling an external API:\n * const start = Date.now();\n * const result = await fetch('https://other-api.com/data');\n * submitRelayFeedback({\n * agentId: '5',\n * success: result.ok,\n * responseTimeMs: Date.now() - start,\n * endpoint: '/data',\n * });\n * ```\n */\nexport function submitRelayFeedback(config: RelayFeedbackConfig): void {\n const agentId = String(config.agentId);\n const endpoint = config.endpoint ?? '';\n const responseTimeMs = config.responseTimeMs ?? 0;\n\n const privateKey = config.feedbackWalletPrivateKey\n ?? (typeof process !== 'undefined'\n ? process.env?.FEEDBACK_WALLET_PRIVATE_KEY ?? process.env?.ERC8004_FEEDBACK_WALLET_PRIVATE_KEY\n : undefined);\n const reputationAddress = config.reputationRegistryAddress\n ?? (typeof process !== 'undefined' ? process.env?.ERC8004_REPUTATION_REGISTRY : undefined);\n const rpcUrl = config.rpcUrl\n ?? (typeof process !== 'undefined' ? process.env?.ERC8004_RPC_URL : undefined)\n ?? 'https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha';\n\n if (!privateKey || !reputationAddress) {\n console.warn('[relai:submitRelayFeedback] FEEDBACK_WALLET_PRIVATE_KEY or ERC8004_REPUTATION_REGISTRY not set — skipping');\n return;\n }\n\n const provider = new ethers.JsonRpcProvider(rpcUrl);\n const signer = new ethers.Wallet(privateKey, provider);\n const reputation = new ethers.Contract(reputationAddress, RELAY_FEEDBACK_REPUTATION_ABI, signer);\n const id = BigInt(agentId);\n\n (async () => {\n const successValue = config.success ? 10000n : 0n;\n try {\n const srTx = await reputation.giveFeedback(\n id, successValue, 2, 'successRate', '', endpoint, '', ethers.ZeroHash,\n );\n await srTx.wait();\n console.log(`[relai:submitRelayFeedback] successRate confirmed agentId=${agentId} success=${config.success}`);\n } catch (err: any) {\n console.warn(`[relai:submitRelayFeedback] successRate failed (non-fatal): ${err?.message}`);\n }\n\n if (responseTimeMs > 0) {\n try {\n const rtTx = await reputation.giveFeedback(\n id, BigInt(Math.max(0, Math.round(responseTimeMs))), 0, 'responseTime', '', endpoint, '', ethers.ZeroHash,\n );\n console.log(`[relai:submitRelayFeedback] responseTime sent agentId=${agentId} ms=${responseTimeMs} tx=${rtTx.hash}`);\n } catch (err: any) {\n console.warn(`[relai:submitRelayFeedback] responseTime failed (non-fatal): ${err?.message}`);\n }\n }\n })();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,oBAAuB;AAsCvB,IAAM,gCAAgC;AAAA,EACpC;AACF;AA2BO,SAAS,oBAAoB,QAAmC;AACrE,QAAM,UAAU,OAAO,OAAO,OAAO;AACrC,QAAM,WAAW,OAAO,YAAY;AACpC,QAAM,iBAAiB,OAAO,kBAAkB;AAEhD,QAAM,aAAa,OAAO,6BACpB,OAAO,YAAY,cACnB,QAAQ,KAAK,+BAA+B,QAAQ,KAAK,sCACzD;AACN,QAAM,oBAAoB,OAAO,8BAC3B,OAAO,YAAY,cAAc,QAAQ,KAAK,8BAA8B;AAClF,QAAM,SAAS,OAAO,WAChB,OAAO,YAAY,cAAc,QAAQ,KAAK,kBAAkB,WACjE;AAEL,MAAI,CAAC,cAAc,CAAC,mBAAmB;AACrC,YAAQ,KAAK,gHAA2G;AACxH;AAAA,EACF;AAEA,QAAM,WAAW,IAAI,qBAAO,gBAAgB,MAAM;AAClD,QAAM,SAAS,IAAI,qBAAO,OAAO,YAAY,QAAQ;AACrD,QAAM,aAAa,IAAI,qBAAO,SAAS,mBAAmB,+BAA+B,MAAM;AAC/F,QAAM,KAAK,OAAO,OAAO;AAEzB,GAAC,YAAY;AACX,UAAM,eAAe,OAAO,UAAU,SAAS;AAC/C,QAAI;AACF,YAAM,OAAO,MAAM,WAAW;AAAA,QAC5B;AAAA,QAAI;AAAA,QAAc;AAAA,QAAG;AAAA,QAAe;AAAA,QAAI;AAAA,QAAU;AAAA,QAAI,qBAAO;AAAA,MAC/D;AACA,YAAM,KAAK,KAAK;AAChB,cAAQ,IAAI,6DAA6D,OAAO,YAAY,OAAO,OAAO,EAAE;AAAA,IAC9G,SAAS,KAAU;AACjB,cAAQ,KAAK,+DAA+D,KAAK,OAAO,EAAE;AAAA,IAC5F;AAEA,QAAI,iBAAiB,GAAG;AACtB,UAAI;AACF,cAAM,OAAO,MAAM,WAAW;AAAA,UAC5B;AAAA,UAAI,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,cAAc,CAAC,CAAC;AAAA,UAAG;AAAA,UAAG;AAAA,UAAgB;AAAA,UAAI;AAAA,UAAU;AAAA,UAAI,qBAAO;AAAA,QACnG;AACA,gBAAQ,IAAI,yDAAyD,OAAO,OAAO,cAAc,OAAO,KAAK,IAAI,EAAE;AAAA,MACrH,SAAS,KAAU;AACjB,gBAAQ,KAAK,gEAAgE,KAAK,OAAO,EAAE;AAAA,MAC7F;AAAA,IACF;AAAA,EACF,GAAG;AACL;","names":[]}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
interface RelayFeedbackConfig {
|
|
2
|
+
/**
|
|
3
|
+
* ERC-8004 agentId (NFT tokenId) of the **target API** you are calling.
|
|
4
|
+
*/
|
|
5
|
+
agentId: string | number;
|
|
6
|
+
/**
|
|
7
|
+
* Whether the API call succeeded.
|
|
8
|
+
*/
|
|
9
|
+
success: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Elapsed milliseconds for the API call.
|
|
12
|
+
*/
|
|
13
|
+
responseTimeMs?: number;
|
|
14
|
+
/**
|
|
15
|
+
* Endpoint path of the called API (e.g. '/v1/data').
|
|
16
|
+
*/
|
|
17
|
+
endpoint?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Private key of the **relay/third-party** wallet that signs feedback.
|
|
20
|
+
* MUST be different from the API owner's wallet — ReputationRegistry
|
|
21
|
+
* may restrict self-feedback. Wallet needs CREDIT tokens on SKALE Base.
|
|
22
|
+
* Default: process.env.FEEDBACK_WALLET_PRIVATE_KEY
|
|
23
|
+
*/
|
|
24
|
+
feedbackWalletPrivateKey?: string;
|
|
25
|
+
/**
|
|
26
|
+
* SKALE Base Sepolia RPC URL.
|
|
27
|
+
* Default: process.env.ERC8004_RPC_URL or SKALE Base Sepolia public RPC.
|
|
28
|
+
*/
|
|
29
|
+
rpcUrl?: string;
|
|
30
|
+
/**
|
|
31
|
+
* ERC-8004 ReputationRegistry contract address.
|
|
32
|
+
* Default: process.env.ERC8004_REPUTATION_REGISTRY
|
|
33
|
+
*/
|
|
34
|
+
reputationRegistryAddress?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Submit ERC-8004 on-chain feedback about a **third-party API** you called.
|
|
38
|
+
*
|
|
39
|
+
* Call this fire-and-forget from your relay/aggregator after every external API call.
|
|
40
|
+
* Uses a separate relay wallet (not the API owner's key) to avoid self-feedback restrictions.
|
|
41
|
+
*
|
|
42
|
+
* Records:
|
|
43
|
+
* - `successRate`: 10000 (= 100%) on success, 0 on failure — 2 decimal places
|
|
44
|
+
* - `responseTime`: elapsed milliseconds
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import { submitRelayFeedback } from '@relai-fi/x402/relay-feedback';
|
|
49
|
+
*
|
|
50
|
+
* // after calling an external API:
|
|
51
|
+
* const start = Date.now();
|
|
52
|
+
* const result = await fetch('https://other-api.com/data');
|
|
53
|
+
* submitRelayFeedback({
|
|
54
|
+
* agentId: '5',
|
|
55
|
+
* success: result.ok,
|
|
56
|
+
* responseTimeMs: Date.now() - start,
|
|
57
|
+
* endpoint: '/data',
|
|
58
|
+
* });
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
declare function submitRelayFeedback(config: RelayFeedbackConfig): void;
|
|
62
|
+
|
|
63
|
+
export { type RelayFeedbackConfig, submitRelayFeedback };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
interface RelayFeedbackConfig {
|
|
2
|
+
/**
|
|
3
|
+
* ERC-8004 agentId (NFT tokenId) of the **target API** you are calling.
|
|
4
|
+
*/
|
|
5
|
+
agentId: string | number;
|
|
6
|
+
/**
|
|
7
|
+
* Whether the API call succeeded.
|
|
8
|
+
*/
|
|
9
|
+
success: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Elapsed milliseconds for the API call.
|
|
12
|
+
*/
|
|
13
|
+
responseTimeMs?: number;
|
|
14
|
+
/**
|
|
15
|
+
* Endpoint path of the called API (e.g. '/v1/data').
|
|
16
|
+
*/
|
|
17
|
+
endpoint?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Private key of the **relay/third-party** wallet that signs feedback.
|
|
20
|
+
* MUST be different from the API owner's wallet — ReputationRegistry
|
|
21
|
+
* may restrict self-feedback. Wallet needs CREDIT tokens on SKALE Base.
|
|
22
|
+
* Default: process.env.FEEDBACK_WALLET_PRIVATE_KEY
|
|
23
|
+
*/
|
|
24
|
+
feedbackWalletPrivateKey?: string;
|
|
25
|
+
/**
|
|
26
|
+
* SKALE Base Sepolia RPC URL.
|
|
27
|
+
* Default: process.env.ERC8004_RPC_URL or SKALE Base Sepolia public RPC.
|
|
28
|
+
*/
|
|
29
|
+
rpcUrl?: string;
|
|
30
|
+
/**
|
|
31
|
+
* ERC-8004 ReputationRegistry contract address.
|
|
32
|
+
* Default: process.env.ERC8004_REPUTATION_REGISTRY
|
|
33
|
+
*/
|
|
34
|
+
reputationRegistryAddress?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Submit ERC-8004 on-chain feedback about a **third-party API** you called.
|
|
38
|
+
*
|
|
39
|
+
* Call this fire-and-forget from your relay/aggregator after every external API call.
|
|
40
|
+
* Uses a separate relay wallet (not the API owner's key) to avoid self-feedback restrictions.
|
|
41
|
+
*
|
|
42
|
+
* Records:
|
|
43
|
+
* - `successRate`: 10000 (= 100%) on success, 0 on failure — 2 decimal places
|
|
44
|
+
* - `responseTime`: elapsed milliseconds
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import { submitRelayFeedback } from '@relai-fi/x402/relay-feedback';
|
|
49
|
+
*
|
|
50
|
+
* // after calling an external API:
|
|
51
|
+
* const start = Date.now();
|
|
52
|
+
* const result = await fetch('https://other-api.com/data');
|
|
53
|
+
* submitRelayFeedback({
|
|
54
|
+
* agentId: '5',
|
|
55
|
+
* success: result.ok,
|
|
56
|
+
* responseTimeMs: Date.now() - start,
|
|
57
|
+
* endpoint: '/data',
|
|
58
|
+
* });
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
declare function submitRelayFeedback(config: RelayFeedbackConfig): void;
|
|
62
|
+
|
|
63
|
+
export { type RelayFeedbackConfig, submitRelayFeedback };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// src/relay-feedback.ts
|
|
2
|
+
import { ethers } from "ethers";
|
|
3
|
+
var RELAY_FEEDBACK_REPUTATION_ABI = [
|
|
4
|
+
"function giveFeedback(uint256 agentId, int128 value, uint8 valueDecimals, string tag1, string tag2, string endpoint, string feedbackURI, bytes32 feedbackHash) external"
|
|
5
|
+
];
|
|
6
|
+
function submitRelayFeedback(config) {
|
|
7
|
+
const agentId = String(config.agentId);
|
|
8
|
+
const endpoint = config.endpoint ?? "";
|
|
9
|
+
const responseTimeMs = config.responseTimeMs ?? 0;
|
|
10
|
+
const privateKey = config.feedbackWalletPrivateKey ?? (typeof process !== "undefined" ? process.env?.FEEDBACK_WALLET_PRIVATE_KEY ?? process.env?.ERC8004_FEEDBACK_WALLET_PRIVATE_KEY : void 0);
|
|
11
|
+
const reputationAddress = config.reputationRegistryAddress ?? (typeof process !== "undefined" ? process.env?.ERC8004_REPUTATION_REGISTRY : void 0);
|
|
12
|
+
const rpcUrl = config.rpcUrl ?? (typeof process !== "undefined" ? process.env?.ERC8004_RPC_URL : void 0) ?? "https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha";
|
|
13
|
+
if (!privateKey || !reputationAddress) {
|
|
14
|
+
console.warn("[relai:submitRelayFeedback] FEEDBACK_WALLET_PRIVATE_KEY or ERC8004_REPUTATION_REGISTRY not set \u2014 skipping");
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const provider = new ethers.JsonRpcProvider(rpcUrl);
|
|
18
|
+
const signer = new ethers.Wallet(privateKey, provider);
|
|
19
|
+
const reputation = new ethers.Contract(reputationAddress, RELAY_FEEDBACK_REPUTATION_ABI, signer);
|
|
20
|
+
const id = BigInt(agentId);
|
|
21
|
+
(async () => {
|
|
22
|
+
const successValue = config.success ? 10000n : 0n;
|
|
23
|
+
try {
|
|
24
|
+
const srTx = await reputation.giveFeedback(
|
|
25
|
+
id,
|
|
26
|
+
successValue,
|
|
27
|
+
2,
|
|
28
|
+
"successRate",
|
|
29
|
+
"",
|
|
30
|
+
endpoint,
|
|
31
|
+
"",
|
|
32
|
+
ethers.ZeroHash
|
|
33
|
+
);
|
|
34
|
+
await srTx.wait();
|
|
35
|
+
console.log(`[relai:submitRelayFeedback] successRate confirmed agentId=${agentId} success=${config.success}`);
|
|
36
|
+
} catch (err) {
|
|
37
|
+
console.warn(`[relai:submitRelayFeedback] successRate failed (non-fatal): ${err?.message}`);
|
|
38
|
+
}
|
|
39
|
+
if (responseTimeMs > 0) {
|
|
40
|
+
try {
|
|
41
|
+
const rtTx = await reputation.giveFeedback(
|
|
42
|
+
id,
|
|
43
|
+
BigInt(Math.max(0, Math.round(responseTimeMs))),
|
|
44
|
+
0,
|
|
45
|
+
"responseTime",
|
|
46
|
+
"",
|
|
47
|
+
endpoint,
|
|
48
|
+
"",
|
|
49
|
+
ethers.ZeroHash
|
|
50
|
+
);
|
|
51
|
+
console.log(`[relai:submitRelayFeedback] responseTime sent agentId=${agentId} ms=${responseTimeMs} tx=${rtTx.hash}`);
|
|
52
|
+
} catch (err) {
|
|
53
|
+
console.warn(`[relai:submitRelayFeedback] responseTime failed (non-fatal): ${err?.message}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
})();
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
submitRelayFeedback
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=relay-feedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/relay-feedback.ts"],"sourcesContent":["// src/relay-feedback.ts\n// Standalone utility for submitting ERC-8004 feedback about third-party APIs.\n// Not a plugin — call directly from your relay/aggregator application code.\n\nimport { ethers } from 'ethers';\n\nexport interface RelayFeedbackConfig {\n /**\n * ERC-8004 agentId (NFT tokenId) of the **target API** you are calling.\n */\n agentId: string | number;\n /**\n * Whether the API call succeeded.\n */\n success: boolean;\n /**\n * Elapsed milliseconds for the API call.\n */\n responseTimeMs?: number;\n /**\n * Endpoint path of the called API (e.g. '/v1/data').\n */\n endpoint?: string;\n /**\n * Private key of the **relay/third-party** wallet that signs feedback.\n * MUST be different from the API owner's wallet — ReputationRegistry\n * may restrict self-feedback. Wallet needs CREDIT tokens on SKALE Base.\n * Default: process.env.FEEDBACK_WALLET_PRIVATE_KEY\n */\n feedbackWalletPrivateKey?: string;\n /**\n * SKALE Base Sepolia RPC URL.\n * Default: process.env.ERC8004_RPC_URL or SKALE Base Sepolia public RPC.\n */\n rpcUrl?: string;\n /**\n * ERC-8004 ReputationRegistry contract address.\n * Default: process.env.ERC8004_REPUTATION_REGISTRY\n */\n reputationRegistryAddress?: string;\n}\n\nconst RELAY_FEEDBACK_REPUTATION_ABI = [\n 'function giveFeedback(uint256 agentId, int128 value, uint8 valueDecimals, string tag1, string tag2, string endpoint, string feedbackURI, bytes32 feedbackHash) external',\n];\n\n/**\n * Submit ERC-8004 on-chain feedback about a **third-party API** you called.\n *\n * Call this fire-and-forget from your relay/aggregator after every external API call.\n * Uses a separate relay wallet (not the API owner's key) to avoid self-feedback restrictions.\n *\n * Records:\n * - `successRate`: 10000 (= 100%) on success, 0 on failure — 2 decimal places\n * - `responseTime`: elapsed milliseconds\n *\n * @example\n * ```typescript\n * import { submitRelayFeedback } from '@relai-fi/x402/relay-feedback';\n *\n * // after calling an external API:\n * const start = Date.now();\n * const result = await fetch('https://other-api.com/data');\n * submitRelayFeedback({\n * agentId: '5',\n * success: result.ok,\n * responseTimeMs: Date.now() - start,\n * endpoint: '/data',\n * });\n * ```\n */\nexport function submitRelayFeedback(config: RelayFeedbackConfig): void {\n const agentId = String(config.agentId);\n const endpoint = config.endpoint ?? '';\n const responseTimeMs = config.responseTimeMs ?? 0;\n\n const privateKey = config.feedbackWalletPrivateKey\n ?? (typeof process !== 'undefined'\n ? process.env?.FEEDBACK_WALLET_PRIVATE_KEY ?? process.env?.ERC8004_FEEDBACK_WALLET_PRIVATE_KEY\n : undefined);\n const reputationAddress = config.reputationRegistryAddress\n ?? (typeof process !== 'undefined' ? process.env?.ERC8004_REPUTATION_REGISTRY : undefined);\n const rpcUrl = config.rpcUrl\n ?? (typeof process !== 'undefined' ? process.env?.ERC8004_RPC_URL : undefined)\n ?? 'https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha';\n\n if (!privateKey || !reputationAddress) {\n console.warn('[relai:submitRelayFeedback] FEEDBACK_WALLET_PRIVATE_KEY or ERC8004_REPUTATION_REGISTRY not set — skipping');\n return;\n }\n\n const provider = new ethers.JsonRpcProvider(rpcUrl);\n const signer = new ethers.Wallet(privateKey, provider);\n const reputation = new ethers.Contract(reputationAddress, RELAY_FEEDBACK_REPUTATION_ABI, signer);\n const id = BigInt(agentId);\n\n (async () => {\n const successValue = config.success ? 10000n : 0n;\n try {\n const srTx = await reputation.giveFeedback(\n id, successValue, 2, 'successRate', '', endpoint, '', ethers.ZeroHash,\n );\n await srTx.wait();\n console.log(`[relai:submitRelayFeedback] successRate confirmed agentId=${agentId} success=${config.success}`);\n } catch (err: any) {\n console.warn(`[relai:submitRelayFeedback] successRate failed (non-fatal): ${err?.message}`);\n }\n\n if (responseTimeMs > 0) {\n try {\n const rtTx = await reputation.giveFeedback(\n id, BigInt(Math.max(0, Math.round(responseTimeMs))), 0, 'responseTime', '', endpoint, '', ethers.ZeroHash,\n );\n console.log(`[relai:submitRelayFeedback] responseTime sent agentId=${agentId} ms=${responseTimeMs} tx=${rtTx.hash}`);\n } catch (err: any) {\n console.warn(`[relai:submitRelayFeedback] responseTime failed (non-fatal): ${err?.message}`);\n }\n }\n })();\n}\n"],"mappings":";AAIA,SAAS,cAAc;AAsCvB,IAAM,gCAAgC;AAAA,EACpC;AACF;AA2BO,SAAS,oBAAoB,QAAmC;AACrE,QAAM,UAAU,OAAO,OAAO,OAAO;AACrC,QAAM,WAAW,OAAO,YAAY;AACpC,QAAM,iBAAiB,OAAO,kBAAkB;AAEhD,QAAM,aAAa,OAAO,6BACpB,OAAO,YAAY,cACnB,QAAQ,KAAK,+BAA+B,QAAQ,KAAK,sCACzD;AACN,QAAM,oBAAoB,OAAO,8BAC3B,OAAO,YAAY,cAAc,QAAQ,KAAK,8BAA8B;AAClF,QAAM,SAAS,OAAO,WAChB,OAAO,YAAY,cAAc,QAAQ,KAAK,kBAAkB,WACjE;AAEL,MAAI,CAAC,cAAc,CAAC,mBAAmB;AACrC,YAAQ,KAAK,gHAA2G;AACxH;AAAA,EACF;AAEA,QAAM,WAAW,IAAI,OAAO,gBAAgB,MAAM;AAClD,QAAM,SAAS,IAAI,OAAO,OAAO,YAAY,QAAQ;AACrD,QAAM,aAAa,IAAI,OAAO,SAAS,mBAAmB,+BAA+B,MAAM;AAC/F,QAAM,KAAK,OAAO,OAAO;AAEzB,GAAC,YAAY;AACX,UAAM,eAAe,OAAO,UAAU,SAAS;AAC/C,QAAI;AACF,YAAM,OAAO,MAAM,WAAW;AAAA,QAC5B;AAAA,QAAI;AAAA,QAAc;AAAA,QAAG;AAAA,QAAe;AAAA,QAAI;AAAA,QAAU;AAAA,QAAI,OAAO;AAAA,MAC/D;AACA,YAAM,KAAK,KAAK;AAChB,cAAQ,IAAI,6DAA6D,OAAO,YAAY,OAAO,OAAO,EAAE;AAAA,IAC9G,SAAS,KAAU;AACjB,cAAQ,KAAK,+DAA+D,KAAK,OAAO,EAAE;AAAA,IAC5F;AAEA,QAAI,iBAAiB,GAAG;AACtB,UAAI;AACF,cAAM,OAAO,MAAM,WAAW;AAAA,UAC5B;AAAA,UAAI,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,cAAc,CAAC,CAAC;AAAA,UAAG;AAAA,UAAG;AAAA,UAAgB;AAAA,UAAI;AAAA,UAAU;AAAA,UAAI,OAAO;AAAA,QACnG;AACA,gBAAQ,IAAI,yDAAyD,OAAO,OAAO,cAAc,OAAO,KAAK,IAAI,EAAE;AAAA,MACrH,SAAS,KAAU;AACjB,gBAAQ,KAAK,gEAAgE,KAAK,OAAO,EAAE;AAAA,MAC7F;AAAA,IACF;AAAA,EACF,GAAG;AACL;","names":[]}
|