agentwallet-sdk 5.0.5 → 5.1.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 +32 -30
- package/dist/ap2/index.d.ts +185 -0
- package/dist/ap2/index.d.ts.map +1 -0
- package/dist/ap2/index.js +255 -0
- package/dist/ap2/index.js.map +1 -0
- package/dist/bridge/unified.d.ts +101 -0
- package/dist/bridge/unified.d.ts.map +1 -0
- package/dist/bridge/unified.js +284 -0
- package/dist/bridge/unified.js.map +1 -0
- package/dist/chains.d.ts +62 -0
- package/dist/chains.d.ts.map +1 -0
- package/dist/chains.js +108 -0
- package/dist/chains.js.map +1 -0
- package/dist/fiat/index.d.ts +10 -0
- package/dist/fiat/index.d.ts.map +1 -0
- package/dist/fiat/index.js +9 -0
- package/dist/fiat/index.js.map +1 -0
- package/dist/fiat/onramp.d.ts +101 -0
- package/dist/fiat/onramp.d.ts.map +1 -0
- package/dist/fiat/onramp.js +155 -0
- package/dist/fiat/onramp.js.map +1 -0
- package/dist/fiat/providers/index.d.ts +16 -0
- package/dist/fiat/providers/index.d.ts.map +1 -0
- package/dist/fiat/providers/index.js +30 -0
- package/dist/fiat/providers/index.js.map +1 -0
- package/dist/fiat/providers/moonpay.d.ts +22 -0
- package/dist/fiat/providers/moonpay.d.ts.map +1 -0
- package/dist/fiat/providers/moonpay.js +107 -0
- package/dist/fiat/providers/moonpay.js.map +1 -0
- package/dist/fiat/providers/stripe.d.ts +26 -0
- package/dist/fiat/providers/stripe.d.ts.map +1 -0
- package/dist/fiat/providers/stripe.js +135 -0
- package/dist/fiat/providers/stripe.js.map +1 -0
- package/dist/fiat/providers/transak.d.ts +26 -0
- package/dist/fiat/providers/transak.d.ts.map +1 -0
- package/dist/fiat/providers/transak.js +119 -0
- package/dist/fiat/providers/transak.js.map +1 -0
- package/dist/fiat/types.d.ts +106 -0
- package/dist/fiat/types.d.ts.map +1 -0
- package/dist/fiat/types.js +13 -0
- package/dist/fiat/types.js.map +1 -0
- package/dist/flash/executor.d.ts +119 -0
- package/dist/flash/executor.d.ts.map +1 -0
- package/dist/flash/executor.js +195 -0
- package/dist/flash/executor.js.map +1 -0
- package/dist/flash/index.d.ts +28 -0
- package/dist/flash/index.d.ts.map +1 -0
- package/dist/flash/index.js +29 -0
- package/dist/flash/index.js.map +1 -0
- package/dist/flash/scanner.d.ts +133 -0
- package/dist/flash/scanner.d.ts.map +1 -0
- package/dist/flash/scanner.js +212 -0
- package/dist/flash/scanner.js.map +1 -0
- package/dist/flash/types.d.ts +136 -0
- package/dist/flash/types.d.ts.map +1 -0
- package/dist/flash/types.js +23 -0
- package/dist/flash/types.js.map +1 -0
- package/dist/gas/index.d.ts +4 -0
- package/dist/gas/index.d.ts.map +1 -0
- package/dist/gas/index.js +3 -0
- package/dist/gas/index.js.map +1 -0
- package/dist/gas/sponsor.d.ts +70 -0
- package/dist/gas/sponsor.d.ts.map +1 -0
- package/dist/gas/sponsor.js +193 -0
- package/dist/gas/sponsor.js.map +1 -0
- package/dist/gas/types.d.ts +76 -0
- package/dist/gas/types.d.ts.map +1 -0
- package/dist/gas/types.js +21 -0
- package/dist/gas/types.js.map +1 -0
- package/dist/identity/agent-identity.d.ts +276 -0
- package/dist/identity/agent-identity.d.ts.map +1 -0
- package/dist/identity/agent-identity.js +300 -0
- package/dist/identity/agent-identity.js.map +1 -0
- package/dist/identity/email-resolver.d.ts +235 -0
- package/dist/identity/email-resolver.js +283 -0
- package/dist/identity/erc6551.d.ts +441 -0
- package/dist/identity/erc6551.d.ts.map +1 -0
- package/dist/identity/erc6551.js +517 -0
- package/dist/identity/erc6551.js.map +1 -0
- package/dist/index.d.ts +286 -213
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/mev/index.d.ts +4 -0
- package/dist/mev/index.d.ts.map +1 -0
- package/dist/mev/index.js +8 -0
- package/dist/mev/index.js.map +1 -0
- package/dist/mev/protection.d.ts +54 -0
- package/dist/mev/protection.d.ts.map +1 -0
- package/dist/mev/protection.js +185 -0
- package/dist/mev/protection.js.map +1 -0
- package/dist/mev/risk.d.ts +19 -0
- package/dist/mev/risk.d.ts.map +1 -0
- package/dist/mev/risk.js +95 -0
- package/dist/mev/risk.js.map +1 -0
- package/dist/mev/types.d.ts +49 -0
- package/dist/mev/types.d.ts.map +1 -0
- package/dist/mev/types.js +2 -0
- package/dist/mev/types.js.map +1 -0
- package/dist/plugins/elizaos.d.ts +52 -0
- package/dist/plugins/elizaos.d.ts.map +1 -0
- package/dist/plugins/elizaos.js +89 -0
- package/dist/plugins/elizaos.js.map +1 -0
- package/dist/settlement/index.d.ts +4 -0
- package/dist/settlement/index.d.ts.map +1 -0
- package/dist/settlement/index.js +3 -0
- package/dist/settlement/index.js.map +1 -0
- package/dist/settlement/types.d.ts +66 -0
- package/dist/settlement/types.d.ts.map +1 -0
- package/dist/settlement/types.js +37 -0
- package/dist/settlement/types.js.map +1 -0
- package/dist/settlement/verifier.d.ts +75 -0
- package/dist/settlement/verifier.d.ts.map +1 -0
- package/dist/settlement/verifier.js +354 -0
- package/dist/settlement/verifier.js.map +1 -0
- package/dist/solana/bridge.d.ts +144 -0
- package/dist/solana/bridge.d.ts.map +1 -0
- package/dist/solana/bridge.js +352 -0
- package/dist/solana/bridge.js.map +1 -0
- package/dist/solana/index.d.ts +8 -0
- package/dist/solana/index.d.ts.map +1 -0
- package/dist/solana/index.js +6 -0
- package/dist/solana/index.js.map +1 -0
- package/dist/solana/swap.d.ts +85 -0
- package/dist/solana/swap.d.ts.map +1 -0
- package/dist/solana/swap.js +173 -0
- package/dist/solana/swap.js.map +1 -0
- package/dist/solana/types.d.ts +126 -0
- package/dist/solana/types.d.ts.map +1 -0
- package/dist/solana/types.js +10 -0
- package/dist/solana/types.js.map +1 -0
- package/dist/solana/wallet.d.ts +83 -0
- package/dist/solana/wallet.d.ts.map +1 -0
- package/dist/solana/wallet.js +164 -0
- package/dist/solana/wallet.js.map +1 -0
- package/dist/solana/x402.d.ts +69 -0
- package/dist/solana/x402.d.ts.map +1 -0
- package/dist/solana/x402.js +154 -0
- package/dist/solana/x402.js.map +1 -0
- package/dist/solver/adapter.d.ts +47 -0
- package/dist/solver/adapter.d.ts.map +1 -0
- package/dist/solver/adapter.js +146 -0
- package/dist/solver/adapter.js.map +1 -0
- package/dist/solver/analyzer.d.ts +48 -0
- package/dist/solver/analyzer.d.ts.map +1 -0
- package/dist/solver/analyzer.js +171 -0
- package/dist/solver/analyzer.js.map +1 -0
- package/dist/solver/builder.d.ts +31 -0
- package/dist/solver/builder.d.ts.map +1 -0
- package/dist/solver/builder.js +60 -0
- package/dist/solver/builder.js.map +1 -0
- package/dist/solver/index.d.ts +22 -0
- package/dist/solver/index.d.ts.map +1 -0
- package/dist/solver/index.js +25 -0
- package/dist/solver/index.js.map +1 -0
- package/dist/solver/types.d.ts +115 -0
- package/dist/solver/types.d.ts.map +1 -0
- package/dist/solver/types.js +10 -0
- package/dist/solver/types.js.map +1 -0
- package/dist/spend-guard/index.d.ts +125 -0
- package/dist/spend-guard/index.d.ts.map +1 -0
- package/dist/spend-guard/index.js +150 -0
- package/dist/spend-guard/index.js.map +1 -0
- package/dist/swap/router/cache.d.ts +13 -0
- package/dist/swap/router/cache.d.ts.map +1 -0
- package/dist/swap/router/cache.js +30 -0
- package/dist/swap/router/cache.js.map +1 -0
- package/dist/swap/router/flashbots.d.ts +10 -0
- package/dist/swap/router/flashbots.d.ts.map +1 -0
- package/dist/swap/router/flashbots.js +43 -0
- package/dist/swap/router/flashbots.js.map +1 -0
- package/dist/swap/router/health.d.ts +17 -0
- package/dist/swap/router/health.d.ts.map +1 -0
- package/dist/swap/router/health.js +38 -0
- package/dist/swap/router/health.js.map +1 -0
- package/dist/swap/router/index.d.ts +10 -0
- package/dist/swap/router/index.d.ts.map +1 -0
- package/dist/swap/router/index.js +10 -0
- package/dist/swap/router/index.js.map +1 -0
- package/dist/swap/router/providers/cowswap.d.ts +11 -0
- package/dist/swap/router/providers/cowswap.d.ts.map +1 -0
- package/dist/swap/router/providers/cowswap.js +79 -0
- package/dist/swap/router/providers/cowswap.js.map +1 -0
- package/dist/swap/router/providers/index.d.ts +20 -0
- package/dist/swap/router/providers/index.d.ts.map +1 -0
- package/dist/swap/router/providers/index.js +32 -0
- package/dist/swap/router/providers/index.js.map +1 -0
- package/dist/swap/router/providers/jupiter.d.ts +12 -0
- package/dist/swap/router/providers/jupiter.d.ts.map +1 -0
- package/dist/swap/router/providers/jupiter.js +73 -0
- package/dist/swap/router/providers/jupiter.js.map +1 -0
- package/dist/swap/router/providers/lifi.d.ts +11 -0
- package/dist/swap/router/providers/lifi.d.ts.map +1 -0
- package/dist/swap/router/providers/lifi.js +123 -0
- package/dist/swap/router/providers/lifi.js.map +1 -0
- package/dist/swap/router/providers/oneinch.d.ts +13 -0
- package/dist/swap/router/providers/oneinch.d.ts.map +1 -0
- package/dist/swap/router/providers/oneinch.js +71 -0
- package/dist/swap/router/providers/oneinch.js.map +1 -0
- package/dist/swap/router/providers/paraswap.d.ts +11 -0
- package/dist/swap/router/providers/paraswap.d.ts.map +1 -0
- package/dist/swap/router/providers/paraswap.js +73 -0
- package/dist/swap/router/providers/paraswap.js.map +1 -0
- package/dist/swap/router/providers/uniswap.d.ts +31 -0
- package/dist/swap/router/providers/uniswap.d.ts.map +1 -0
- package/dist/swap/router/providers/uniswap.js +237 -0
- package/dist/swap/router/providers/uniswap.js.map +1 -0
- package/dist/swap/router/providers/zerox.d.ts +13 -0
- package/dist/swap/router/providers/zerox.d.ts.map +1 -0
- package/dist/swap/router/providers/zerox.js +94 -0
- package/dist/swap/router/providers/zerox.js.map +1 -0
- package/dist/swap/router/router.d.ts +86 -0
- package/dist/swap/router/router.d.ts.map +1 -0
- package/dist/swap/router/router.js +224 -0
- package/dist/swap/router/router.js.map +1 -0
- package/dist/swap/router/rsi/engine.d.ts +60 -0
- package/dist/swap/router/rsi/engine.d.ts.map +1 -0
- package/dist/swap/router/rsi/engine.js +483 -0
- package/dist/swap/router/rsi/engine.js.map +1 -0
- package/dist/swap/router/rsi/index.d.ts +3 -0
- package/dist/swap/router/rsi/index.d.ts.map +1 -0
- package/dist/swap/router/rsi/index.js +3 -0
- package/dist/swap/router/rsi/index.js.map +1 -0
- package/dist/swap/router/rsi/types.d.ts +106 -0
- package/dist/swap/router/rsi/types.d.ts.map +1 -0
- package/dist/swap/router/rsi/types.js +3 -0
- package/dist/swap/router/rsi/types.js.map +1 -0
- package/dist/swap/router/types.d.ts +120 -0
- package/dist/swap/router/types.d.ts.map +1 -0
- package/dist/swap/router/types.js +16 -0
- package/dist/swap/router/types.js.map +1 -0
- package/dist/tax/engine.d.ts +131 -0
- package/dist/tax/engine.d.ts.map +1 -0
- package/dist/tax/engine.js +307 -0
- package/dist/tax/engine.js.map +1 -0
- package/dist/tax/index.d.ts +9 -0
- package/dist/tax/index.d.ts.map +1 -0
- package/dist/tax/index.js +12 -0
- package/dist/tax/index.js.map +1 -0
- package/dist/tax/lots.d.ts +60 -0
- package/dist/tax/lots.d.ts.map +1 -0
- package/dist/tax/lots.js +129 -0
- package/dist/tax/lots.js.map +1 -0
- package/dist/tax/types.d.ts +113 -0
- package/dist/tax/types.d.ts.map +1 -0
- package/dist/tax/types.js +18 -0
- package/dist/tax/types.js.map +1 -0
- package/dist/verifiable-intent/index.d.ts +84 -0
- package/dist/verifiable-intent/index.js +385 -0
- package/dist/yield/index.d.ts +26 -0
- package/dist/yield/index.d.ts.map +1 -0
- package/dist/yield/index.js +29 -0
- package/dist/yield/index.js.map +1 -0
- package/dist/yield/rates.d.ts +114 -0
- package/dist/yield/rates.d.ts.map +1 -0
- package/dist/yield/rates.js +351 -0
- package/dist/yield/rates.js.map +1 -0
- package/dist/yield/types.d.ts +134 -0
- package/dist/yield/types.d.ts.map +1 -0
- package/dist/yield/types.js +24 -0
- package/dist/yield/types.js.map +1 -0
- package/dist/yield/vault.d.ts +112 -0
- package/dist/yield/vault.d.ts.map +1 -0
- package/dist/yield/vault.js +264 -0
- package/dist/yield/vault.js.map +1 -0
- package/package.json +3 -3
- package/LICENSE +0 -21
- package/dist/x402/chains/stellar/index.d.ts +0 -136
- package/dist/x402/chains/stellar/index.d.ts.map +0 -1
- package/dist/x402/chains/stellar/index.js +0 -190
- package/dist/x402/chains/stellar/index.js.map +0 -1
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EmailResolver — AgentMail integration for agentwallet-sdk.
|
|
3
|
+
* Gives every agent its own email inbox and resolves emails to wallet addresses.
|
|
4
|
+
*
|
|
5
|
+
* AgentMail API: https://api.agentmail.to/v0
|
|
6
|
+
* Docs: https://docs.agentmail.to
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const DEFAULT_BASE_URL = 'https://api.agentmail.to/v0';
|
|
10
|
+
const DEFAULT_CACHE_TTL = 300; // 5 minutes
|
|
11
|
+
|
|
12
|
+
// ── x402 payment request format embedded in email bodies ──────────────────────
|
|
13
|
+
const X402_PAYMENT_HEADER = '<!-- x402-payment-request';
|
|
14
|
+
const X402_PAYMENT_FOOTER = 'x402-payment-request -->';
|
|
15
|
+
|
|
16
|
+
function encodePaymentRequest(req) {
|
|
17
|
+
return `\n\n${X402_PAYMENT_HEADER}\n${JSON.stringify(req, null, 2)}\n${X402_PAYMENT_FOOTER}\n`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function parsePaymentRequest(body) {
|
|
21
|
+
const start = body.indexOf(X402_PAYMENT_HEADER);
|
|
22
|
+
const end = body.indexOf(X402_PAYMENT_FOOTER);
|
|
23
|
+
if (start === -1 || end === -1) return undefined;
|
|
24
|
+
try {
|
|
25
|
+
const json = body.slice(start + X402_PAYMENT_HEADER.length, end).trim();
|
|
26
|
+
return JSON.parse(json);
|
|
27
|
+
} catch {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ── API client helpers ─────────────────────────────────────────────────────────
|
|
33
|
+
|
|
34
|
+
async function agentMailRequest(apiKey, baseUrl, method, path, body) {
|
|
35
|
+
const url = `${baseUrl}${path}`;
|
|
36
|
+
const opts = {
|
|
37
|
+
method,
|
|
38
|
+
headers: {
|
|
39
|
+
Authorization: `Bearer ${apiKey}`,
|
|
40
|
+
'Content-Type': 'application/json',
|
|
41
|
+
Accept: 'application/json',
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
if (body !== undefined) {
|
|
45
|
+
opts.body = JSON.stringify(body);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const res = await fetch(url, opts);
|
|
49
|
+
if (!res.ok) {
|
|
50
|
+
const text = await res.text().catch(() => '(no body)');
|
|
51
|
+
throw new Error(`AgentMail API error ${res.status}: ${text}`);
|
|
52
|
+
}
|
|
53
|
+
if (res.status === 204) return undefined;
|
|
54
|
+
return res.json();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// ── Map AgentMail inbox response → AgentInbox ─────────────────────────────────
|
|
58
|
+
|
|
59
|
+
function mapInbox(raw) {
|
|
60
|
+
// AgentMail inbox shape: { id, username, domain, display_name, created_at, ... }
|
|
61
|
+
const email = raw.username && raw.domain
|
|
62
|
+
? `${raw.username}@${raw.domain}`
|
|
63
|
+
: raw.email_address ?? raw.address ?? '';
|
|
64
|
+
return {
|
|
65
|
+
emailAddress: email,
|
|
66
|
+
inboxId: raw.id ?? raw.inbox_id,
|
|
67
|
+
displayName: raw.display_name ?? raw.displayName ?? '',
|
|
68
|
+
createdAt: raw.created_at ?? raw.createdAt ?? new Date().toISOString(),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ── Map AgentMail message response → AgentEmail ───────────────────────────────
|
|
73
|
+
|
|
74
|
+
function mapMessage(raw) {
|
|
75
|
+
const body = raw.body?.text ?? raw.text ?? raw.body ?? '';
|
|
76
|
+
return {
|
|
77
|
+
messageId: raw.id ?? raw.message_id,
|
|
78
|
+
from: raw.from ?? raw.sender ?? '',
|
|
79
|
+
to: Array.isArray(raw.to) ? raw.to : [raw.to ?? ''],
|
|
80
|
+
subject: raw.subject ?? '',
|
|
81
|
+
body,
|
|
82
|
+
timestamp: raw.timestamp ?? raw.received_at ?? raw.created_at ?? '',
|
|
83
|
+
threadId: raw.thread_id ?? raw.threadId,
|
|
84
|
+
paymentRequest: parsePaymentRequest(body),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ── EmailResolver class ───────────────────────────────────────────────────────
|
|
89
|
+
|
|
90
|
+
export class EmailResolver {
|
|
91
|
+
constructor(config) {
|
|
92
|
+
if (!config?.agentMailApiKey) {
|
|
93
|
+
throw new Error('EmailResolver: agentMailApiKey is required');
|
|
94
|
+
}
|
|
95
|
+
this.apiKey = config.agentMailApiKey;
|
|
96
|
+
this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL;
|
|
97
|
+
this.cacheTtl = config.cacheTtlSeconds ?? DEFAULT_CACHE_TTL;
|
|
98
|
+
this.cache = new Map();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// ── Inbox management ────────────────────────────────────────────────────────
|
|
102
|
+
|
|
103
|
+
async createInbox({ agentName, displayName, walletAddress, chain = 'base' }) {
|
|
104
|
+
if (!agentName) throw new Error('agentName is required');
|
|
105
|
+
if (!walletAddress) throw new Error('walletAddress is required');
|
|
106
|
+
|
|
107
|
+
// AgentMail inbox creation — username becomes the local part of the email
|
|
108
|
+
const raw = await agentMailRequest(this.apiKey, this.baseUrl, 'POST', '/inboxes', {
|
|
109
|
+
username: agentName.toLowerCase().replace(/[^a-z0-9-]/g, '-'),
|
|
110
|
+
display_name: displayName,
|
|
111
|
+
// Store wallet metadata in AgentMail's custom fields
|
|
112
|
+
metadata: {
|
|
113
|
+
wallet_address: walletAddress,
|
|
114
|
+
chain,
|
|
115
|
+
sdk: 'agentwallet-sdk',
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
return mapInbox(raw);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async listInboxes() {
|
|
123
|
+
const data = await agentMailRequest(this.apiKey, this.baseUrl, 'GET', '/inboxes');
|
|
124
|
+
const items = data?.inboxes ?? data?.items ?? (Array.isArray(data) ? data : []);
|
|
125
|
+
return items.map(mapInbox);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async getInbox(inboxId) {
|
|
129
|
+
const raw = await agentMailRequest(this.apiKey, this.baseUrl, 'GET', `/inboxes/${inboxId}`);
|
|
130
|
+
return mapInbox(raw);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async deleteInbox(inboxId) {
|
|
134
|
+
await agentMailRequest(this.apiKey, this.baseUrl, 'DELETE', `/inboxes/${inboxId}`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// ── Email ↔ Wallet resolution ───────────────────────────────────────────────
|
|
138
|
+
|
|
139
|
+
async resolveEmailToWallet(emailAddress) {
|
|
140
|
+
const normalised = emailAddress.toLowerCase().trim();
|
|
141
|
+
|
|
142
|
+
// 1. Cache hit
|
|
143
|
+
const cached = this.cache.get(normalised);
|
|
144
|
+
if (cached && Date.now() / 1000 - cached.resolvedAt < this.cacheTtl) {
|
|
145
|
+
return cached;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// 2. AgentMail lookup — scan inboxes for matching email + wallet metadata
|
|
149
|
+
try {
|
|
150
|
+
const inboxes = await this.listInboxes();
|
|
151
|
+
for (const inbox of inboxes) {
|
|
152
|
+
if (inbox.emailAddress.toLowerCase() === normalised) {
|
|
153
|
+
// Fetch full inbox to get metadata
|
|
154
|
+
const full = await agentMailRequest(
|
|
155
|
+
this.apiKey, this.baseUrl, 'GET', `/inboxes/${inbox.inboxId}`
|
|
156
|
+
);
|
|
157
|
+
const walletAddress = full?.metadata?.wallet_address;
|
|
158
|
+
const chain = full?.metadata?.chain ?? 'base';
|
|
159
|
+
if (walletAddress) {
|
|
160
|
+
const resolution = {
|
|
161
|
+
emailAddress: normalised,
|
|
162
|
+
walletAddress,
|
|
163
|
+
chain,
|
|
164
|
+
source: 'agentmail',
|
|
165
|
+
resolvedAt: Math.floor(Date.now() / 1000),
|
|
166
|
+
};
|
|
167
|
+
this.cache.set(normalised, resolution);
|
|
168
|
+
return resolution;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
} catch (err) {
|
|
173
|
+
// Fall through to ENS
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// 3. ENS fallback — resolve agent.eth-style names
|
|
177
|
+
// e.g., agent@ens.agentmail.to → agent.eth
|
|
178
|
+
if (normalised.includes('@ens.')) {
|
|
179
|
+
const localPart = normalised.split('@')[0];
|
|
180
|
+
const ensName = `${localPart}.eth`;
|
|
181
|
+
// ENS resolution requires viem — import dynamically to avoid hard dep
|
|
182
|
+
try {
|
|
183
|
+
const { createPublicClient, http } = await import('viem');
|
|
184
|
+
const { mainnet } = await import('viem/chains');
|
|
185
|
+
const client = createPublicClient({ chain: mainnet, transport: http() });
|
|
186
|
+
const addr = await client.getEnsAddress({ name: ensName });
|
|
187
|
+
if (addr) {
|
|
188
|
+
const resolution = {
|
|
189
|
+
emailAddress: normalised,
|
|
190
|
+
walletAddress: addr,
|
|
191
|
+
chain: 'ethereum',
|
|
192
|
+
source: 'ens',
|
|
193
|
+
resolvedAt: Math.floor(Date.now() / 1000),
|
|
194
|
+
};
|
|
195
|
+
this.cache.set(normalised, resolution);
|
|
196
|
+
return resolution;
|
|
197
|
+
}
|
|
198
|
+
} catch {
|
|
199
|
+
// ENS lookup failed
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
throw new Error(`EmailResolver: could not resolve wallet for ${emailAddress}`);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async resolveWalletToEmail(walletAddress) {
|
|
207
|
+
const normalised = walletAddress.toLowerCase().trim();
|
|
208
|
+
try {
|
|
209
|
+
const inboxes = await this.listInboxes();
|
|
210
|
+
for (const inbox of inboxes) {
|
|
211
|
+
const full = await agentMailRequest(
|
|
212
|
+
this.apiKey, this.baseUrl, 'GET', `/inboxes/${inbox.inboxId}`
|
|
213
|
+
);
|
|
214
|
+
if (full?.metadata?.wallet_address?.toLowerCase() === normalised) {
|
|
215
|
+
return inbox.emailAddress;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
} catch {
|
|
219
|
+
// ignore
|
|
220
|
+
}
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// ── Messaging ───────────────────────────────────────────────────────────────
|
|
225
|
+
|
|
226
|
+
async fetchMessages(inboxId, options = {}) {
|
|
227
|
+
const params = new URLSearchParams();
|
|
228
|
+
if (options.unreadOnly) params.set('unread', 'true');
|
|
229
|
+
if (options.limit) params.set('limit', String(options.limit));
|
|
230
|
+
if (options.threadId) params.set('thread_id', options.threadId);
|
|
231
|
+
|
|
232
|
+
const qs = params.toString();
|
|
233
|
+
const path = `/inboxes/${inboxId}/messages${qs ? `?${qs}` : ''}`;
|
|
234
|
+
const data = await agentMailRequest(this.apiKey, this.baseUrl, 'GET', path);
|
|
235
|
+
const items = data?.messages ?? data?.items ?? (Array.isArray(data) ? data : []);
|
|
236
|
+
return items.map(mapMessage);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async sendEmail({ inboxId, to, subject, body, paymentRequest, replyToMessageId }) {
|
|
240
|
+
const recipients = Array.isArray(to) ? to : [to];
|
|
241
|
+
let fullBody = body;
|
|
242
|
+
if (paymentRequest) {
|
|
243
|
+
fullBody += encodePaymentRequest(paymentRequest);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const payload = {
|
|
247
|
+
to: recipients,
|
|
248
|
+
subject,
|
|
249
|
+
body: { text: fullBody },
|
|
250
|
+
};
|
|
251
|
+
if (replyToMessageId) {
|
|
252
|
+
payload.reply_to_message_id = replyToMessageId;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const result = await agentMailRequest(
|
|
256
|
+
this.apiKey, this.baseUrl, 'POST', `/inboxes/${inboxId}/messages`, payload
|
|
257
|
+
);
|
|
258
|
+
return { messageId: result?.id ?? result?.message_id };
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
async replyToEmail({ inboxId, messageId, body, paymentRequest }) {
|
|
262
|
+
let fullBody = body;
|
|
263
|
+
if (paymentRequest) {
|
|
264
|
+
fullBody += encodePaymentRequest(paymentRequest);
|
|
265
|
+
}
|
|
266
|
+
const result = await agentMailRequest(
|
|
267
|
+
this.apiKey, this.baseUrl, 'POST', `/inboxes/${inboxId}/messages/${messageId}/reply`,
|
|
268
|
+
{ body: { text: fullBody } }
|
|
269
|
+
);
|
|
270
|
+
return { messageId: result?.id ?? result?.message_id };
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
async markAsRead(inboxId, messageId) {
|
|
274
|
+
await agentMailRequest(
|
|
275
|
+
this.apiKey, this.baseUrl, 'PATCH', `/inboxes/${inboxId}/messages/${messageId}`,
|
|
276
|
+
{ read: true }
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
clearCache() {
|
|
281
|
+
this.cache.clear();
|
|
282
|
+
}
|
|
283
|
+
}
|