@q00bs/agent-sdk 1.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/Q00bsAgent.d.ts +331 -0
- package/dist/Q00bsAgent.d.ts.map +1 -0
- package/dist/Q00bsAgent.js +695 -0
- package/dist/Q00bsAgent.js.map +1 -0
- package/dist/abis/AgentEscrow.d.ts +336 -0
- package/dist/abis/AgentEscrow.d.ts.map +1 -0
- package/dist/abis/AgentEscrow.js +206 -0
- package/dist/abis/AgentEscrow.js.map +1 -0
- package/dist/abis/AgentRegistry.d.ts +496 -0
- package/dist/abis/AgentRegistry.d.ts.map +1 -0
- package/dist/abis/AgentRegistry.js +280 -0
- package/dist/abis/AgentRegistry.js.map +1 -0
- package/dist/abis/ConsensusModule.d.ts +270 -0
- package/dist/abis/ConsensusModule.d.ts.map +1 -0
- package/dist/abis/ConsensusModule.js +157 -0
- package/dist/abis/ConsensusModule.js.map +1 -0
- package/dist/abis/ERC8004Identity.d.ts +293 -0
- package/dist/abis/ERC8004Identity.d.ts.map +1 -0
- package/dist/abis/ERC8004Identity.js +223 -0
- package/dist/abis/ERC8004Identity.js.map +1 -0
- package/dist/abis/ERC8004Reputation.d.ts +362 -0
- package/dist/abis/ERC8004Reputation.d.ts.map +1 -0
- package/dist/abis/ERC8004Reputation.js +229 -0
- package/dist/abis/ERC8004Reputation.js.map +1 -0
- package/dist/abis/ERC8004Validation.d.ts +234 -0
- package/dist/abis/ERC8004Validation.d.ts.map +1 -0
- package/dist/abis/ERC8004Validation.js +162 -0
- package/dist/abis/ERC8004Validation.js.map +1 -0
- package/dist/abis/Q00bFactory.d.ts +123 -0
- package/dist/abis/Q00bFactory.d.ts.map +1 -0
- package/dist/abis/Q00bFactory.js +65 -0
- package/dist/abis/Q00bFactory.js.map +1 -0
- package/dist/abis/TheQ00bs.d.ts +119 -0
- package/dist/abis/TheQ00bs.d.ts.map +1 -0
- package/dist/abis/TheQ00bs.js +73 -0
- package/dist/abis/TheQ00bs.js.map +1 -0
- package/dist/abis/index.d.ts +9 -0
- package/dist/abis/index.d.ts.map +1 -0
- package/dist/abis/index.js +17 -0
- package/dist/abis/index.js.map +1 -0
- package/dist/client.d.ts +111 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +134 -0
- package/dist/client.js.map +1 -0
- package/dist/consensus.d.ts +85 -0
- package/dist/consensus.d.ts.map +1 -0
- package/dist/consensus.js +227 -0
- package/dist/consensus.js.map +1 -0
- package/dist/constants.d.ts +85 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +113 -0
- package/dist/constants.js.map +1 -0
- package/dist/discovery.d.ts +70 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +214 -0
- package/dist/discovery.js.map +1 -0
- package/dist/erc8004.d.ts +311 -0
- package/dist/erc8004.d.ts.map +1 -0
- package/dist/erc8004.js +824 -0
- package/dist/erc8004.js.map +1 -0
- package/dist/errors.d.ts +107 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +210 -0
- package/dist/errors.js.map +1 -0
- package/dist/escrow.d.ts +86 -0
- package/dist/escrow.d.ts.map +1 -0
- package/dist/escrow.js +267 -0
- package/dist/escrow.js.map +1 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +118 -0
- package/dist/index.js.map +1 -0
- package/dist/privy.d.ts +197 -0
- package/dist/privy.d.ts.map +1 -0
- package/dist/privy.js +524 -0
- package/dist/privy.js.map +1 -0
- package/dist/trust.d.ts +49 -0
- package/dist/trust.d.ts.map +1 -0
- package/dist/trust.js +117 -0
- package/dist/trust.js.map +1 -0
- package/dist/types.d.ts +472 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +36 -0
- package/dist/types.js.map +1 -0
- package/package.json +30 -0
package/dist/privy.js
ADDED
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @q00bs/agent-sdk — Privy Wallet Manager
|
|
4
|
+
*
|
|
5
|
+
* This module integrates Privy's server-side wallet API to give each
|
|
6
|
+
* Q00bs agent a custody-free wallet with built-in spending policies.
|
|
7
|
+
*
|
|
8
|
+
* WHY THIS EXISTS:
|
|
9
|
+
* Raw private keys in env vars are a security liability for autonomous agents.
|
|
10
|
+
* Privy holds key material in a secure enclave and enforces transaction policies
|
|
11
|
+
* BEFORE signing. This is the same pattern used by OpenClaw agents:
|
|
12
|
+
* https://privy.io/blog/securely-equipping-openclaw-agents-with-privy-wallets
|
|
13
|
+
*
|
|
14
|
+
* ARCHITECTURE:
|
|
15
|
+
* ┌──────────────────┐ ┌──────────────────┐ ┌────────────┐
|
|
16
|
+
* │ Q00bsAgent SDK │────▶│ Privy Server API │────▶│ Base L2 │
|
|
17
|
+
* │ (your agent) │ │ (policy check + │ │ (on-chain) │
|
|
18
|
+
* │ │ │ key custody) │ │ │
|
|
19
|
+
* └──────────────────┘ └──────────────────┘ └────────────┘
|
|
20
|
+
*
|
|
21
|
+
* 1. Agent calls createWallet() or getWallet() via this module.
|
|
22
|
+
* 2. Privy provisions a wallet with a policy (spend limits, allowed contracts).
|
|
23
|
+
* 3. Agent sends transactions via sendTransaction() — Privy checks policy, signs, broadcasts.
|
|
24
|
+
* 4. Private key NEVER leaves Privy's secure infrastructure.
|
|
25
|
+
*
|
|
26
|
+
* SECURITY PRINCIPLES (from Privy's guide):
|
|
27
|
+
* 1. Always attach policies at wallet creation
|
|
28
|
+
* 2. Validate every transaction (destination, amount, chain)
|
|
29
|
+
* 3. Protect credentials (app secret never in agent prompts/memory)
|
|
30
|
+
* 4. Guard against prompt injection
|
|
31
|
+
* 5. Require explicit confirmation for security-weakening changes
|
|
32
|
+
*/
|
|
33
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
+
exports.PrivyWalletManager = void 0;
|
|
35
|
+
const errors_1 = require("./errors");
|
|
36
|
+
const constants_1 = require("./constants");
|
|
37
|
+
// ─────────────────────────────────────────────────────────────
|
|
38
|
+
// PRIVY API BASE URL
|
|
39
|
+
// ─────────────────────────────────────────────────────────────
|
|
40
|
+
const PRIVY_API_BASE = 'https://auth.privy.io/api/v1';
|
|
41
|
+
// ─────────────────────────────────────────────────────────────
|
|
42
|
+
// PRIVY WALLET MANAGER
|
|
43
|
+
// ─────────────────────────────────────────────────────────────
|
|
44
|
+
/**
|
|
45
|
+
* Manages Privy server wallets for Q00bs agents.
|
|
46
|
+
*
|
|
47
|
+
* Each agent gets a dedicated wallet with a policy that mirrors its
|
|
48
|
+
* on-chain AgentPermissions. Three layers of defense:
|
|
49
|
+
* Layer 1: Privy policy (server-side, instant reject)
|
|
50
|
+
* Layer 2: SDK pre-validation (local check before API call)
|
|
51
|
+
* Layer 3: Smart contract modifiers (on-chain, final authority)
|
|
52
|
+
*
|
|
53
|
+
* USAGE:
|
|
54
|
+
* ```ts
|
|
55
|
+
* const manager = new PrivyWalletManager({
|
|
56
|
+
* appId: process.env.PRIVY_APP_ID!,
|
|
57
|
+
* appSecret: process.env.PRIVY_APP_SECRET!,
|
|
58
|
+
* }, logger);
|
|
59
|
+
*
|
|
60
|
+
* // Create a new agent wallet with spending policies
|
|
61
|
+
* const wallet = await manager.createWallet({
|
|
62
|
+
* name: 'ResearchBot #47 Limits',
|
|
63
|
+
* rules: [
|
|
64
|
+
* { type: 'max_transaction_value', value: '0.1' },
|
|
65
|
+
* { type: 'daily_spend_limit', value: '1.0' },
|
|
66
|
+
* { type: 'allowed_chains', value: [8453] }, // Base only
|
|
67
|
+
* { type: 'allowed_contracts', value: ['0xRegistryAddress', '0xEscrowAddress'] },
|
|
68
|
+
* ],
|
|
69
|
+
* });
|
|
70
|
+
*
|
|
71
|
+
* // Send a transaction through Privy (policy-checked + signed)
|
|
72
|
+
* const result = await manager.sendTransaction(wallet.walletId, {
|
|
73
|
+
* to: '0xEscrowContract',
|
|
74
|
+
* data: '0x...', // encoded createEscrow() call
|
|
75
|
+
* value: '0x2386F26FC10000', // 0.01 ETH in hex
|
|
76
|
+
* });
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
class PrivyWalletManager {
|
|
80
|
+
config;
|
|
81
|
+
logger;
|
|
82
|
+
authHeaders;
|
|
83
|
+
// Track current wallet info
|
|
84
|
+
_walletInfo;
|
|
85
|
+
/** The current wallet info (set after createWallet/getWallet). */
|
|
86
|
+
get walletInfo() {
|
|
87
|
+
return this._walletInfo;
|
|
88
|
+
}
|
|
89
|
+
/** The wallet's Ethereum address (or undefined if not initialized). */
|
|
90
|
+
get address() {
|
|
91
|
+
return this._walletInfo?.address;
|
|
92
|
+
}
|
|
93
|
+
constructor(config, logger) {
|
|
94
|
+
if (!config.appId) {
|
|
95
|
+
throw new errors_1.PrivyWalletError('Privy appId is required');
|
|
96
|
+
}
|
|
97
|
+
if (!config.appSecret) {
|
|
98
|
+
throw new errors_1.PrivyWalletError('Privy appSecret is required (server-side only)');
|
|
99
|
+
}
|
|
100
|
+
this.config = config;
|
|
101
|
+
this.logger = logger;
|
|
102
|
+
// Privy uses Basic auth: base64(appId:appSecret)
|
|
103
|
+
const credentials = Buffer.from(`${config.appId}:${config.appSecret}`).toString('base64');
|
|
104
|
+
this.authHeaders = {
|
|
105
|
+
'Authorization': `Basic ${credentials}`,
|
|
106
|
+
'privy-app-id': config.appId,
|
|
107
|
+
'Content-Type': 'application/json',
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// ─────────────────────────────────────────────────────────────
|
|
111
|
+
// WALLET LIFECYCLE
|
|
112
|
+
// ─────────────────────────────────────────────────────────────
|
|
113
|
+
/**
|
|
114
|
+
* Create a new Privy server wallet for this agent.
|
|
115
|
+
*
|
|
116
|
+
* This provisions a fresh Ethereum wallet in Privy's secure enclave
|
|
117
|
+
* and attaches the specified spending policy. The private key NEVER
|
|
118
|
+
* leaves Privy — it exists only in their HSM.
|
|
119
|
+
*
|
|
120
|
+
* @param policy - Spending policy to enforce on this wallet.
|
|
121
|
+
* @returns Info about the newly created wallet.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```ts
|
|
125
|
+
* const wallet = await manager.createWallet({
|
|
126
|
+
* name: 'DataBot Spending Limits',
|
|
127
|
+
* rules: [
|
|
128
|
+
* { type: 'max_transaction_value', value: '0.1', description: 'Max 0.1 ETH per tx' },
|
|
129
|
+
* { type: 'daily_spend_limit', value: '1.0', description: 'Max 1 ETH per day' },
|
|
130
|
+
* { type: 'allowed_chains', value: [8453] },
|
|
131
|
+
* ],
|
|
132
|
+
* });
|
|
133
|
+
* console.log(`Agent wallet created: ${wallet.address}`);
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
async createWallet(policy) {
|
|
137
|
+
this.logger.info('Creating new Privy server wallet for agent...');
|
|
138
|
+
try {
|
|
139
|
+
const body = {
|
|
140
|
+
chain_type: 'ethereum',
|
|
141
|
+
};
|
|
142
|
+
// If a user ID is set, link the wallet to the owner's Privy account
|
|
143
|
+
if (this.config.userId) {
|
|
144
|
+
body.user_id = this.config.userId;
|
|
145
|
+
}
|
|
146
|
+
const response = await fetch(`${PRIVY_API_BASE}/wallets`, {
|
|
147
|
+
method: 'POST',
|
|
148
|
+
headers: this.authHeaders,
|
|
149
|
+
body: JSON.stringify(body),
|
|
150
|
+
});
|
|
151
|
+
if (!response.ok) {
|
|
152
|
+
const errorBody = await response.text();
|
|
153
|
+
throw new errors_1.PrivyApiError(response.status, errorBody);
|
|
154
|
+
}
|
|
155
|
+
const data = await response.json();
|
|
156
|
+
const walletInfo = {
|
|
157
|
+
walletId: data.id,
|
|
158
|
+
address: data.address,
|
|
159
|
+
chainId: constants_1.BASE_CHAIN_ID,
|
|
160
|
+
policy,
|
|
161
|
+
isNew: true,
|
|
162
|
+
};
|
|
163
|
+
this._walletInfo = walletInfo;
|
|
164
|
+
this.logger.info(`Privy wallet created: ${walletInfo.address} (ID: ${walletInfo.walletId})`);
|
|
165
|
+
// If policy was provided, attach it to the wallet
|
|
166
|
+
if (policy) {
|
|
167
|
+
await this.setPolicy(walletInfo.walletId, policy);
|
|
168
|
+
}
|
|
169
|
+
return walletInfo;
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
if (error instanceof errors_1.PrivyApiError)
|
|
173
|
+
throw error;
|
|
174
|
+
throw new errors_1.PrivyWalletError(`Failed to create wallet: ${error.message}`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Retrieve an existing Privy wallet by its ID.
|
|
179
|
+
*
|
|
180
|
+
* @param walletId - The Privy wallet ID (from a previous createWallet call).
|
|
181
|
+
* @returns Info about the existing wallet.
|
|
182
|
+
*/
|
|
183
|
+
async getWallet(walletId) {
|
|
184
|
+
this.logger.info(`Fetching Privy wallet ${walletId}...`);
|
|
185
|
+
try {
|
|
186
|
+
const response = await fetch(`${PRIVY_API_BASE}/wallets/${walletId}`, {
|
|
187
|
+
method: 'GET',
|
|
188
|
+
headers: this.authHeaders,
|
|
189
|
+
});
|
|
190
|
+
if (!response.ok) {
|
|
191
|
+
const errorBody = await response.text();
|
|
192
|
+
throw new errors_1.PrivyApiError(response.status, errorBody);
|
|
193
|
+
}
|
|
194
|
+
const data = await response.json();
|
|
195
|
+
const walletInfo = {
|
|
196
|
+
walletId: data.id,
|
|
197
|
+
address: data.address,
|
|
198
|
+
chainId: constants_1.BASE_CHAIN_ID,
|
|
199
|
+
isNew: false,
|
|
200
|
+
};
|
|
201
|
+
this._walletInfo = walletInfo;
|
|
202
|
+
this.logger.info(`Privy wallet loaded: ${walletInfo.address}`);
|
|
203
|
+
return walletInfo;
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
if (error instanceof errors_1.PrivyApiError)
|
|
207
|
+
throw error;
|
|
208
|
+
throw new errors_1.PrivyWalletError(`Failed to fetch wallet: ${error.message}`, walletId);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Initialize the wallet — either load an existing one or create a new one.
|
|
213
|
+
*
|
|
214
|
+
* @param policy - Policy to use if creating a new wallet.
|
|
215
|
+
* @returns The wallet info.
|
|
216
|
+
*/
|
|
217
|
+
async initialize(policy) {
|
|
218
|
+
if (this.config.walletId) {
|
|
219
|
+
return this.getWallet(this.config.walletId);
|
|
220
|
+
}
|
|
221
|
+
return this.createWallet(policy);
|
|
222
|
+
}
|
|
223
|
+
// ─────────────────────────────────────────────────────────────
|
|
224
|
+
// POLICY MANAGEMENT
|
|
225
|
+
// ─────────────────────────────────────────────────────────────
|
|
226
|
+
/**
|
|
227
|
+
* Attach or update a spending policy on a Privy wallet.
|
|
228
|
+
*
|
|
229
|
+
* Policies are the key security layer for agentic wallets. They define:
|
|
230
|
+
* - Max value per transaction
|
|
231
|
+
* - Daily spending cap
|
|
232
|
+
* - Allowed contract addresses (whitelist)
|
|
233
|
+
* - Allowed chains (e.g. Base only)
|
|
234
|
+
* - Function selector whitelist
|
|
235
|
+
* - Human approval requirements for high-value actions
|
|
236
|
+
*
|
|
237
|
+
* @param walletId - The wallet to apply the policy to.
|
|
238
|
+
* @param policy - The policy definition.
|
|
239
|
+
*/
|
|
240
|
+
async setPolicy(walletId, policy) {
|
|
241
|
+
this.logger.info(`Setting policy "${policy.name}" on wallet ${walletId}`);
|
|
242
|
+
try {
|
|
243
|
+
// Convert our policy format to Privy's API format
|
|
244
|
+
const privyPolicy = this.convertToPrivyPolicy(policy);
|
|
245
|
+
const response = await fetch(`${PRIVY_API_BASE}/wallets/${walletId}/policy`, {
|
|
246
|
+
method: 'PUT',
|
|
247
|
+
headers: this.authHeaders,
|
|
248
|
+
body: JSON.stringify(privyPolicy),
|
|
249
|
+
});
|
|
250
|
+
if (!response.ok) {
|
|
251
|
+
const errorBody = await response.text();
|
|
252
|
+
throw new errors_1.PrivyApiError(response.status, errorBody);
|
|
253
|
+
}
|
|
254
|
+
// Update cached wallet info with new policy
|
|
255
|
+
if (this._walletInfo && this._walletInfo.walletId === walletId) {
|
|
256
|
+
this._walletInfo.policy = policy;
|
|
257
|
+
}
|
|
258
|
+
this.logger.info(`Policy "${policy.name}" applied successfully (${policy.rules.length} rules)`);
|
|
259
|
+
}
|
|
260
|
+
catch (error) {
|
|
261
|
+
if (error instanceof errors_1.PrivyApiError)
|
|
262
|
+
throw error;
|
|
263
|
+
throw new errors_1.PrivyWalletError(`Failed to set policy: ${error.message}`, walletId);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Build a default policy from Q00bs AgentPermissions.
|
|
268
|
+
*
|
|
269
|
+
* This translates on-chain permission parameters into Privy policy rules,
|
|
270
|
+
* ensuring the server-side guard matches the on-chain guard.
|
|
271
|
+
*
|
|
272
|
+
* @param maxTxValueEth - Max ETH per transaction (e.g. '0.1').
|
|
273
|
+
* @param dailyLimitEth - Max ETH per day (e.g. '1.0').
|
|
274
|
+
* @param allowedContracts - Contract addresses the agent can interact with.
|
|
275
|
+
* @param requireHumanApproval - Whether to require human approval for high-value txs.
|
|
276
|
+
* @returns A PrivyWalletPolicy ready to attach.
|
|
277
|
+
*/
|
|
278
|
+
static buildDefaultPolicy(maxTxValueEth = '0.1', dailyLimitEth = '1.0', allowedContracts = [], requireHumanApproval = true) {
|
|
279
|
+
const rules = [
|
|
280
|
+
{
|
|
281
|
+
type: 'max_transaction_value',
|
|
282
|
+
value: maxTxValueEth,
|
|
283
|
+
description: `Max ${maxTxValueEth} ETH per transaction`,
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
type: 'daily_spend_limit',
|
|
287
|
+
value: dailyLimitEth,
|
|
288
|
+
description: `Max ${dailyLimitEth} ETH total per 24 hours`,
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
type: 'allowed_chains',
|
|
292
|
+
value: [constants_1.BASE_CHAIN_ID.toString()],
|
|
293
|
+
description: 'Base mainnet only (chain 8453)',
|
|
294
|
+
},
|
|
295
|
+
];
|
|
296
|
+
if (allowedContracts.length > 0) {
|
|
297
|
+
rules.push({
|
|
298
|
+
type: 'allowed_contracts',
|
|
299
|
+
value: allowedContracts,
|
|
300
|
+
description: `Only interact with ${allowedContracts.length} whitelisted contracts`,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
if (requireHumanApproval) {
|
|
304
|
+
rules.push({
|
|
305
|
+
type: 'require_human_approval',
|
|
306
|
+
value: true,
|
|
307
|
+
description: 'Require human owner approval for policy-exceeding actions',
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
return {
|
|
311
|
+
name: 'Q00bs Agent Spending Policy',
|
|
312
|
+
rules,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
// ─────────────────────────────────────────────────────────────
|
|
316
|
+
// TRANSACTIONS
|
|
317
|
+
// ─────────────────────────────────────────────────────────────
|
|
318
|
+
/**
|
|
319
|
+
* Send a transaction through Privy.
|
|
320
|
+
*
|
|
321
|
+
* Privy validates the transaction against the wallet's policy BEFORE signing.
|
|
322
|
+
* If the policy rejects it, a PrivyPolicyViolationError is thrown and
|
|
323
|
+
* nothing is broadcast to the network.
|
|
324
|
+
*
|
|
325
|
+
* @param walletId - The Privy wallet ID to send from.
|
|
326
|
+
* @param tx - Transaction parameters (to, value, data, etc.).
|
|
327
|
+
* @returns Transaction hash and policy status.
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```ts
|
|
331
|
+
* const result = await manager.sendTransaction(walletId, {
|
|
332
|
+
* to: escrowContractAddress,
|
|
333
|
+
* data: encodedCalldata,
|
|
334
|
+
* value: parseEther('0.01').toString(16),
|
|
335
|
+
* chainId: 8453,
|
|
336
|
+
* });
|
|
337
|
+
* console.log(`TX hash: ${result.hash}`);
|
|
338
|
+
* ```
|
|
339
|
+
*/
|
|
340
|
+
async sendTransaction(walletId, tx) {
|
|
341
|
+
this.logger.info(`Sending transaction from wallet ${walletId} to ${tx.to}`);
|
|
342
|
+
// SDK-level pre-validation (Layer 2 — fail fast before hitting Privy API)
|
|
343
|
+
this.preValidateTransaction(walletId, tx);
|
|
344
|
+
try {
|
|
345
|
+
const response = await fetch(`${PRIVY_API_BASE}/wallets/${walletId}/rpc`, {
|
|
346
|
+
method: 'POST',
|
|
347
|
+
headers: this.authHeaders,
|
|
348
|
+
body: JSON.stringify({
|
|
349
|
+
method: 'eth_sendTransaction',
|
|
350
|
+
params: {
|
|
351
|
+
transaction: {
|
|
352
|
+
to: tx.to,
|
|
353
|
+
value: tx.value ? `0x${BigInt(tx.value).toString(16)}` : undefined,
|
|
354
|
+
data: tx.data,
|
|
355
|
+
chain_id: tx.chainId || constants_1.BASE_CHAIN_ID,
|
|
356
|
+
gas_limit: tx.gasLimit,
|
|
357
|
+
},
|
|
358
|
+
},
|
|
359
|
+
}),
|
|
360
|
+
});
|
|
361
|
+
if (!response.ok) {
|
|
362
|
+
const errorBody = await response.text();
|
|
363
|
+
// Check if this is a policy violation
|
|
364
|
+
if (response.status === 403) {
|
|
365
|
+
throw new errors_1.PrivyPolicyViolationError('transaction_policy', errorBody);
|
|
366
|
+
}
|
|
367
|
+
throw new errors_1.PrivyApiError(response.status, errorBody);
|
|
368
|
+
}
|
|
369
|
+
const data = await response.json();
|
|
370
|
+
const result = {
|
|
371
|
+
hash: data.hash,
|
|
372
|
+
policyPassed: true,
|
|
373
|
+
};
|
|
374
|
+
this.logger.info(`Transaction sent: ${result.hash}`);
|
|
375
|
+
return result;
|
|
376
|
+
}
|
|
377
|
+
catch (error) {
|
|
378
|
+
if (error instanceof errors_1.PrivyPolicyViolationError) {
|
|
379
|
+
this.logger.warn(`Transaction blocked by policy: ${error.reason}`);
|
|
380
|
+
throw error;
|
|
381
|
+
}
|
|
382
|
+
if (error instanceof errors_1.PrivyApiError)
|
|
383
|
+
throw error;
|
|
384
|
+
throw new errors_1.PrivyWalletError(`Failed to send transaction: ${error.message}`, walletId);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Sign a message with the Privy wallet (for SIWE, EIP-712, etc.).
|
|
389
|
+
*
|
|
390
|
+
* @param walletId - The Privy wallet ID.
|
|
391
|
+
* @param message - The message to sign.
|
|
392
|
+
* @returns The signature hex string.
|
|
393
|
+
*/
|
|
394
|
+
async signMessage(walletId, message) {
|
|
395
|
+
this.logger.info(`Signing message with wallet ${walletId}`);
|
|
396
|
+
try {
|
|
397
|
+
const response = await fetch(`${PRIVY_API_BASE}/wallets/${walletId}/rpc`, {
|
|
398
|
+
method: 'POST',
|
|
399
|
+
headers: this.authHeaders,
|
|
400
|
+
body: JSON.stringify({
|
|
401
|
+
method: 'personal_sign',
|
|
402
|
+
params: {
|
|
403
|
+
message,
|
|
404
|
+
},
|
|
405
|
+
}),
|
|
406
|
+
});
|
|
407
|
+
if (!response.ok) {
|
|
408
|
+
const errorBody = await response.text();
|
|
409
|
+
throw new errors_1.PrivyApiError(response.status, errorBody);
|
|
410
|
+
}
|
|
411
|
+
const data = await response.json();
|
|
412
|
+
return data.signature;
|
|
413
|
+
}
|
|
414
|
+
catch (error) {
|
|
415
|
+
if (error instanceof errors_1.PrivyApiError)
|
|
416
|
+
throw error;
|
|
417
|
+
throw new errors_1.PrivyWalletError(`Failed to sign message: ${error.message}`, walletId);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Sign typed data (EIP-712) with the Privy wallet.
|
|
422
|
+
*
|
|
423
|
+
* @param walletId - The Privy wallet ID.
|
|
424
|
+
* @param typedData - The EIP-712 typed data object.
|
|
425
|
+
* @returns The signature hex string.
|
|
426
|
+
*/
|
|
427
|
+
async signTypedData(walletId, typedData) {
|
|
428
|
+
this.logger.info(`Signing typed data with wallet ${walletId}`);
|
|
429
|
+
try {
|
|
430
|
+
const response = await fetch(`${PRIVY_API_BASE}/wallets/${walletId}/rpc`, {
|
|
431
|
+
method: 'POST',
|
|
432
|
+
headers: this.authHeaders,
|
|
433
|
+
body: JSON.stringify({
|
|
434
|
+
method: 'eth_signTypedData_v4',
|
|
435
|
+
params: {
|
|
436
|
+
typed_data: typedData,
|
|
437
|
+
},
|
|
438
|
+
}),
|
|
439
|
+
});
|
|
440
|
+
if (!response.ok) {
|
|
441
|
+
const errorBody = await response.text();
|
|
442
|
+
throw new errors_1.PrivyApiError(response.status, errorBody);
|
|
443
|
+
}
|
|
444
|
+
const data = await response.json();
|
|
445
|
+
return data.signature;
|
|
446
|
+
}
|
|
447
|
+
catch (error) {
|
|
448
|
+
if (error instanceof errors_1.PrivyApiError)
|
|
449
|
+
throw error;
|
|
450
|
+
throw new errors_1.PrivyWalletError(`Failed to sign typed data: ${error.message}`, walletId);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
// ─────────────────────────────────────────────────────────────
|
|
454
|
+
// PRIVATE HELPERS
|
|
455
|
+
// ─────────────────────────────────────────────────────────────
|
|
456
|
+
/**
|
|
457
|
+
* SDK-level pre-validation before hitting the Privy API.
|
|
458
|
+
* This catches obvious errors instantly without a network round-trip.
|
|
459
|
+
*/
|
|
460
|
+
preValidateTransaction(walletId, tx) {
|
|
461
|
+
if (!tx.to) {
|
|
462
|
+
throw new errors_1.PrivyWalletError('Transaction "to" address is required', walletId);
|
|
463
|
+
}
|
|
464
|
+
if (!tx.to.startsWith('0x') || tx.to.length !== 42) {
|
|
465
|
+
throw new errors_1.PrivyWalletError(`Invalid "to" address: ${tx.to}`, walletId);
|
|
466
|
+
}
|
|
467
|
+
// Validate against cached policy (if available)
|
|
468
|
+
const policy = this._walletInfo?.policy;
|
|
469
|
+
if (policy && tx.value) {
|
|
470
|
+
const valueBigInt = BigInt(tx.value);
|
|
471
|
+
for (const rule of policy.rules) {
|
|
472
|
+
if (rule.type === 'max_transaction_value' && typeof rule.value === 'string') {
|
|
473
|
+
const maxWei = BigInt(Math.floor(parseFloat(rule.value) * 1e18));
|
|
474
|
+
if (valueBigInt > maxWei) {
|
|
475
|
+
throw new errors_1.PrivyPolicyViolationError('max_transaction_value', `${valueBigInt} wei exceeds max ${maxWei} wei (${rule.value} ETH)`);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
if (rule.type === 'allowed_chains' && Array.isArray(rule.value)) {
|
|
479
|
+
const chainId = tx.chainId || constants_1.BASE_CHAIN_ID;
|
|
480
|
+
if (!rule.value.includes(chainId.toString()) && !rule.value.includes(chainId)) {
|
|
481
|
+
throw new errors_1.PrivyPolicyViolationError('allowed_chains', `Chain ${chainId} is not in the allowed list: ${rule.value.join(', ')}`);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
if (rule.type === 'allowed_contracts' && Array.isArray(rule.value)) {
|
|
485
|
+
const normalizedTo = tx.to.toLowerCase();
|
|
486
|
+
const allowed = rule.value.map((addr) => addr.toLowerCase());
|
|
487
|
+
if (!allowed.includes(normalizedTo)) {
|
|
488
|
+
throw new errors_1.PrivyPolicyViolationError('allowed_contracts', `Contract ${tx.to} is not in the allowed list`);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Convert our PrivyWalletPolicy to Privy's API format.
|
|
496
|
+
*/
|
|
497
|
+
convertToPrivyPolicy(policy) {
|
|
498
|
+
const rules = policy.rules.map((rule) => ({
|
|
499
|
+
type: this.mapRuleType(rule.type),
|
|
500
|
+
value: rule.value,
|
|
501
|
+
description: rule.description,
|
|
502
|
+
}));
|
|
503
|
+
return {
|
|
504
|
+
name: policy.name,
|
|
505
|
+
rules,
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Map our rule type names to Privy's API rule type names.
|
|
510
|
+
*/
|
|
511
|
+
mapRuleType(type) {
|
|
512
|
+
const mapping = {
|
|
513
|
+
'max_transaction_value': 'native_transfer_limit',
|
|
514
|
+
'daily_spend_limit': 'spending_limit_daily',
|
|
515
|
+
'allowed_contracts': 'contract_allowlist',
|
|
516
|
+
'allowed_chains': 'chain_allowlist',
|
|
517
|
+
'allowed_functions': 'function_allowlist',
|
|
518
|
+
'require_human_approval': 'approval_required',
|
|
519
|
+
};
|
|
520
|
+
return mapping[type] || type;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
exports.PrivyWalletManager = PrivyWalletManager;
|
|
524
|
+
//# sourceMappingURL=privy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"privy.js","sourceRoot":"","sources":["../src/privy.ts"],"names":[],"mappings":"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"}
|
package/dist/trust.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @q00bs/agent-sdk — Trust Module
|
|
3
|
+
*
|
|
4
|
+
* Resolves trust paths between agents through the q00b graph.
|
|
5
|
+
*
|
|
6
|
+
* HOW TRUST WORKS:
|
|
7
|
+
* 1. Every agent is registered on one side (0-5) of its owner's q00b.
|
|
8
|
+
* 2. Q00bs are connected through shared tokens (holder of a side token = connected).
|
|
9
|
+
* 3. "Hops" = how many q00b-to-q00b links separate two agents' owners.
|
|
10
|
+
* 4. Trust decays 15% per hop, with a 10% floor.
|
|
11
|
+
* 5. Agents can only communicate within their configured max-hop limit.
|
|
12
|
+
*
|
|
13
|
+
* The on-chain AgentRegistry provides canCommunicate() and getEffectiveTrust().
|
|
14
|
+
* This module wraps those calls with caching and friendly return types.
|
|
15
|
+
*/
|
|
16
|
+
import type { PublicClient, Chain, Transport } from 'viem';
|
|
17
|
+
import type { TrustPath, Logger } from './types';
|
|
18
|
+
export declare class TrustResolver {
|
|
19
|
+
private client;
|
|
20
|
+
private registryAddress;
|
|
21
|
+
private logger;
|
|
22
|
+
/** Simple in-memory cache: "agentA-agentB" → { result, timestamp } */
|
|
23
|
+
private cache;
|
|
24
|
+
private cacheTtlMs;
|
|
25
|
+
constructor(client: PublicClient<Transport, Chain>, registryAddress: string, logger: Logger);
|
|
26
|
+
/**
|
|
27
|
+
* Check whether two agents have a trust path and how strong it is.
|
|
28
|
+
*
|
|
29
|
+
* @param agentA - First agent's on-chain ID.
|
|
30
|
+
* @param agentB - Second agent's on-chain ID.
|
|
31
|
+
* @returns TrustPath with connection status, path length, and effective trust.
|
|
32
|
+
* @throws TrustPathNotFoundError if agents are not connected.
|
|
33
|
+
*/
|
|
34
|
+
resolve(agentA: number, agentB: number): Promise<TrustPath>;
|
|
35
|
+
/**
|
|
36
|
+
* Calculate effective trust locally (without a contract call).
|
|
37
|
+
* Useful for UI previews before committing to a transaction.
|
|
38
|
+
*
|
|
39
|
+
* @param baseTrustScore - Agent's raw trust score (0-10000).
|
|
40
|
+
* @param hops - Number of hops between the two agents' owners.
|
|
41
|
+
* @returns Effective trust score (0-10000).
|
|
42
|
+
*/
|
|
43
|
+
static calculateLocally(baseTrustScore: number, hops: number): number;
|
|
44
|
+
/** Clear the trust cache (useful after on-chain state changes). */
|
|
45
|
+
clearCache(): void;
|
|
46
|
+
/** Set cache TTL in milliseconds. */
|
|
47
|
+
setCacheTtl(ms: number): void;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=trust.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust.d.ts","sourceRoot":"","sources":["../src/trust.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAQ3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAMjD,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,eAAe,CAAgB;IACvC,OAAO,CAAC,MAAM,CAAS;IAEvB,sEAAsE;IACtE,OAAO,CAAC,KAAK,CAA+D;IAC5E,OAAO,CAAC,UAAU,CAAU;gBAG1B,MAAM,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,EACtC,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM;IAOhB;;;;;;;OAOG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IA2DjE;;;;;;;OAOG;IACH,MAAM,CAAC,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAOrE,mEAAmE;IACnE,UAAU,IAAI,IAAI;IAKlB,qCAAqC;IACrC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;CAG9B"}
|