@azeth/sdk 0.2.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/LICENSE +21 -0
- package/README.md +139 -0
- package/dist/account/balance.d.ts +41 -0
- package/dist/account/balance.d.ts.map +1 -0
- package/dist/account/balance.js +264 -0
- package/dist/account/balance.js.map +1 -0
- package/dist/account/create.d.ts +27 -0
- package/dist/account/create.d.ts.map +1 -0
- package/dist/account/create.js +116 -0
- package/dist/account/create.js.map +1 -0
- package/dist/account/deposit.d.ts +34 -0
- package/dist/account/deposit.d.ts.map +1 -0
- package/dist/account/deposit.js +88 -0
- package/dist/account/deposit.js.map +1 -0
- package/dist/account/guardian-approval.d.ts +111 -0
- package/dist/account/guardian-approval.d.ts.map +1 -0
- package/dist/account/guardian-approval.js +223 -0
- package/dist/account/guardian-approval.js.map +1 -0
- package/dist/account/guardian.d.ts +27 -0
- package/dist/account/guardian.d.ts.map +1 -0
- package/dist/account/guardian.js +67 -0
- package/dist/account/guardian.js.map +1 -0
- package/dist/account/history.d.ts +22 -0
- package/dist/account/history.d.ts.map +1 -0
- package/dist/account/history.js +144 -0
- package/dist/account/history.js.map +1 -0
- package/dist/account/transfer.d.ts +28 -0
- package/dist/account/transfer.d.ts.map +1 -0
- package/dist/account/transfer.js +137 -0
- package/dist/account/transfer.js.map +1 -0
- package/dist/auth/erc8128.d.ts +14 -0
- package/dist/auth/erc8128.d.ts.map +1 -0
- package/dist/auth/erc8128.js +92 -0
- package/dist/auth/erc8128.js.map +1 -0
- package/dist/client.d.ts +394 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +970 -0
- package/dist/client.js.map +1 -0
- package/dist/events/emitter.d.ts +96 -0
- package/dist/events/emitter.d.ts.map +1 -0
- package/dist/events/emitter.js +90 -0
- package/dist/events/emitter.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/messaging/message-router.d.ts +69 -0
- package/dist/messaging/message-router.d.ts.map +1 -0
- package/dist/messaging/message-router.js +307 -0
- package/dist/messaging/message-router.js.map +1 -0
- package/dist/messaging/rate-limiter.d.ts +31 -0
- package/dist/messaging/rate-limiter.d.ts.map +1 -0
- package/dist/messaging/rate-limiter.js +74 -0
- package/dist/messaging/rate-limiter.js.map +1 -0
- package/dist/messaging/xmtp.d.ts +144 -0
- package/dist/messaging/xmtp.d.ts.map +1 -0
- package/dist/messaging/xmtp.js +473 -0
- package/dist/messaging/xmtp.js.map +1 -0
- package/dist/payments/agreements.d.ts +87 -0
- package/dist/payments/agreements.d.ts.map +1 -0
- package/dist/payments/agreements.js +337 -0
- package/dist/payments/agreements.js.map +1 -0
- package/dist/payments/budget.d.ts +118 -0
- package/dist/payments/budget.d.ts.map +1 -0
- package/dist/payments/budget.js +176 -0
- package/dist/payments/budget.js.map +1 -0
- package/dist/payments/smart-fetch.d.ts +65 -0
- package/dist/payments/smart-fetch.d.ts.map +1 -0
- package/dist/payments/smart-fetch.js +115 -0
- package/dist/payments/smart-fetch.js.map +1 -0
- package/dist/payments/x402.d.ts +89 -0
- package/dist/payments/x402.d.ts.map +1 -0
- package/dist/payments/x402.js +620 -0
- package/dist/payments/x402.js.map +1 -0
- package/dist/registry/discover.d.ts +43 -0
- package/dist/registry/discover.d.ts.map +1 -0
- package/dist/registry/discover.js +272 -0
- package/dist/registry/discover.js.map +1 -0
- package/dist/registry/register.d.ts +44 -0
- package/dist/registry/register.d.ts.map +1 -0
- package/dist/registry/register.js +126 -0
- package/dist/registry/register.js.map +1 -0
- package/dist/reputation/opinion.d.ts +52 -0
- package/dist/reputation/opinion.d.ts.map +1 -0
- package/dist/reputation/opinion.js +198 -0
- package/dist/reputation/opinion.js.map +1 -0
- package/dist/utils/addresses.d.ts +6 -0
- package/dist/utils/addresses.d.ts.map +1 -0
- package/dist/utils/addresses.js +53 -0
- package/dist/utils/addresses.js.map +1 -0
- package/dist/utils/errors.d.ts +23 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +188 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/execution.d.ts +20 -0
- package/dist/utils/execution.d.ts.map +1 -0
- package/dist/utils/execution.js +28 -0
- package/dist/utils/execution.js.map +1 -0
- package/dist/utils/paymaster.d.ts +35 -0
- package/dist/utils/paymaster.d.ts.map +1 -0
- package/dist/utils/paymaster.js +115 -0
- package/dist/utils/paymaster.js.map +1 -0
- package/dist/utils/retry.d.ts +19 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +68 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/userop.d.ts +55 -0
- package/dist/utils/userop.d.ts.map +1 -0
- package/dist/utils/userop.js +201 -0
- package/dist/utils/userop.js.map +1 -0
- package/dist/utils/validation.d.ts +8 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +35 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { http } from 'viem';
|
|
2
|
+
import { entryPoint07Address } from 'viem/account-abstraction';
|
|
3
|
+
import { createPimlicoClient } from 'permissionless/clients/pimlico';
|
|
4
|
+
/** In-memory daily sponsorship counter.
|
|
5
|
+
* Resets at midnight UTC by tracking the current date string. */
|
|
6
|
+
class SponsorshipCounter {
|
|
7
|
+
counts = new Map();
|
|
8
|
+
currentDay = '';
|
|
9
|
+
/** Increment and return the new count for the given account.
|
|
10
|
+
* Returns 0-based pre-increment count (i.e., the count BEFORE this call). */
|
|
11
|
+
incrementAndGet(account) {
|
|
12
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
13
|
+
if (today !== this.currentDay) {
|
|
14
|
+
this.counts.clear();
|
|
15
|
+
this.currentDay = today;
|
|
16
|
+
}
|
|
17
|
+
const key = account.toLowerCase();
|
|
18
|
+
const current = this.counts.get(key) ?? 0;
|
|
19
|
+
this.counts.set(key, current + 1);
|
|
20
|
+
return current;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const dailyCounter = new SponsorshipCounter();
|
|
24
|
+
/** Estimate total gas cost in wei from UserOp gas fields.
|
|
25
|
+
* Uses maxFeePerGas * (callGasLimit + verificationGasLimit + preVerificationGas)
|
|
26
|
+
* as a conservative upper bound. Returns 0n if fields are missing. */
|
|
27
|
+
function estimateGasCostWei(params) {
|
|
28
|
+
const maxFeePerGas = params['maxFeePerGas'];
|
|
29
|
+
const callGasLimit = params['callGasLimit'];
|
|
30
|
+
const verificationGasLimit = params['verificationGasLimit'];
|
|
31
|
+
const preVerificationGas = params['preVerificationGas'];
|
|
32
|
+
if (!maxFeePerGas)
|
|
33
|
+
return 0n;
|
|
34
|
+
const totalGas = (callGasLimit ?? 0n) + (verificationGasLimit ?? 0n) + (preVerificationGas ?? 0n);
|
|
35
|
+
return maxFeePerGas * totalGas;
|
|
36
|
+
}
|
|
37
|
+
/** Check if the policy allows sponsoring this UserOp.
|
|
38
|
+
* Returns a reason string if denied, undefined if allowed. */
|
|
39
|
+
export function checkPolicy(policy, params) {
|
|
40
|
+
if (!policy)
|
|
41
|
+
return undefined;
|
|
42
|
+
const sender = params['sender'];
|
|
43
|
+
// Check allowedAccounts
|
|
44
|
+
if (policy.allowedAccounts && policy.allowedAccounts.length > 0 && sender) {
|
|
45
|
+
const allowed = policy.allowedAccounts.some((a) => a.toLowerCase() === sender.toLowerCase());
|
|
46
|
+
if (!allowed) {
|
|
47
|
+
return `Account ${sender} not in paymaster allowedAccounts`;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Check daily limit
|
|
51
|
+
if (policy.maxSponsoredPerDay && policy.maxSponsoredPerDay > 0 && sender) {
|
|
52
|
+
const countBefore = dailyCounter.incrementAndGet(sender);
|
|
53
|
+
if (countBefore >= policy.maxSponsoredPerDay) {
|
|
54
|
+
return `Account ${sender} exceeded daily sponsorship limit (${policy.maxSponsoredPerDay})`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Check max gas cost
|
|
58
|
+
if (policy.maxGasCostWei && policy.maxGasCostWei > 0n) {
|
|
59
|
+
const cost = estimateGasCostWei(params);
|
|
60
|
+
if (cost > 0n && cost > policy.maxGasCostWei) {
|
|
61
|
+
return `Estimated gas cost ${cost} wei exceeds maxGasCostWei ${policy.maxGasCostWei}`;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
/** Create a paymaster middleware that wraps a PimlicoClient with graceful fallback
|
|
67
|
+
* and optional policy enforcement.
|
|
68
|
+
*
|
|
69
|
+
* When the paymaster is unreachable or rejects the UserOp, the middleware returns
|
|
70
|
+
* empty paymaster data so the UserOp falls back to self-paid gas.
|
|
71
|
+
*
|
|
72
|
+
* @param paymasterUrl - URL for the paymaster RPC endpoint
|
|
73
|
+
* @param policy - Optional sponsorship policy for client-side filtering
|
|
74
|
+
* @returns PaymasterMiddleware compatible with permissionless's createSmartAccountClient
|
|
75
|
+
*/
|
|
76
|
+
export function createPaymasterMiddleware(paymasterUrl, policy) {
|
|
77
|
+
const pimlicoClient = createPimlicoClient({
|
|
78
|
+
transport: http(paymasterUrl),
|
|
79
|
+
entryPoint: { address: entryPoint07Address, version: '0.7' },
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
getPaymasterData: async (params) => {
|
|
83
|
+
// Policy check before calling the paymaster
|
|
84
|
+
const policyDenial = checkPolicy(policy, params);
|
|
85
|
+
if (policyDenial) {
|
|
86
|
+
console.warn(`[azeth] Paymaster policy denied: ${policyDenial}. Falling back to self-paid gas.`);
|
|
87
|
+
return {};
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
return await pimlicoClient.getPaymasterData(params);
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
94
|
+
console.warn(`[azeth] Paymaster getPaymasterData failed: ${message}. Falling back to self-paid gas.`);
|
|
95
|
+
return {};
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
getPaymasterStubData: async (params) => {
|
|
99
|
+
// Policy check applies to stub data too (same sender, same policy)
|
|
100
|
+
const policyDenial = checkPolicy(policy, params);
|
|
101
|
+
if (policyDenial) {
|
|
102
|
+
return {};
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
return await pimlicoClient.getPaymasterStubData(params);
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
109
|
+
console.warn(`[azeth] Paymaster getPaymasterStubData failed: ${message}. Falling back to self-paid gas.`);
|
|
110
|
+
return {};
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=paymaster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paymaster.js","sourceRoot":"","sources":["../../src/utils/paymaster.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface RetryOptions {
|
|
2
|
+
/** Maximum number of retry attempts (default: 3) */
|
|
3
|
+
maxRetries?: number;
|
|
4
|
+
/** Base delay in ms before first retry (default: 1000) */
|
|
5
|
+
baseDelay?: number;
|
|
6
|
+
/** Maximum delay in ms between retries (default: 10000) */
|
|
7
|
+
maxDelay?: number;
|
|
8
|
+
/** Custom predicate to determine if an error is retryable */
|
|
9
|
+
retryOn?: (error: unknown) => boolean;
|
|
10
|
+
}
|
|
11
|
+
/** Execute a function with exponential backoff retry logic.
|
|
12
|
+
*
|
|
13
|
+
* Retries on network errors and 5xx-like failures by default.
|
|
14
|
+
* Uses exponential backoff with jitter to avoid thundering herd.
|
|
15
|
+
*
|
|
16
|
+
* @throws The last error encountered after all retries are exhausted
|
|
17
|
+
*/
|
|
18
|
+
export declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
19
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;CACvC;AAsCD;;;;;;GAMG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,CAAC,CAAC,CA6BZ"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { AzethError } from '@azeth/common';
|
|
2
|
+
/** LOW-8 fix: Retryable Node.js error codes (stable across versions, unlike message strings) */
|
|
3
|
+
const RETRYABLE_ERROR_CODES = new Set([
|
|
4
|
+
'ECONNREFUSED', 'ECONNRESET', 'ETIMEDOUT', 'ENOTFOUND',
|
|
5
|
+
'EHOSTUNREACH', 'ENETUNREACH', 'EPIPE', 'UND_ERR_CONNECT_TIMEOUT',
|
|
6
|
+
'UND_ERR_SOCKET', 'UND_ERR_HEADERS_TIMEOUT',
|
|
7
|
+
]);
|
|
8
|
+
/** Default retry predicate: retries on network errors and 5xx status codes */
|
|
9
|
+
function isRetryableError(error) {
|
|
10
|
+
if (error instanceof AzethError) {
|
|
11
|
+
return error.code === 'NETWORK_ERROR';
|
|
12
|
+
}
|
|
13
|
+
if (error instanceof TypeError && error.message.includes('fetch')) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
if (error instanceof Error) {
|
|
17
|
+
// LOW-8 fix: Prefer stable error codes over fragile string matching.
|
|
18
|
+
// Node.js system errors (and undici) expose a `code` property.
|
|
19
|
+
const errCode = error.code;
|
|
20
|
+
if (errCode && RETRYABLE_ERROR_CODES.has(errCode)) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
// Fallback: string matching for environments without error codes
|
|
24
|
+
const msg = error.message.toLowerCase();
|
|
25
|
+
return msg.includes('network') ||
|
|
26
|
+
msg.includes('econnrefused') ||
|
|
27
|
+
msg.includes('econnreset') ||
|
|
28
|
+
msg.includes('etimedout') ||
|
|
29
|
+
msg.includes('socket hang up') ||
|
|
30
|
+
msg.includes('503') ||
|
|
31
|
+
msg.includes('502') ||
|
|
32
|
+
msg.includes('429');
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
/** Execute a function with exponential backoff retry logic.
|
|
37
|
+
*
|
|
38
|
+
* Retries on network errors and 5xx-like failures by default.
|
|
39
|
+
* Uses exponential backoff with jitter to avoid thundering herd.
|
|
40
|
+
*
|
|
41
|
+
* @throws The last error encountered after all retries are exhausted
|
|
42
|
+
*/
|
|
43
|
+
export async function withRetry(fn, options) {
|
|
44
|
+
const maxRetries = options?.maxRetries ?? 3;
|
|
45
|
+
const baseDelay = options?.baseDelay ?? 1000;
|
|
46
|
+
const maxDelay = options?.maxDelay ?? 10000;
|
|
47
|
+
const retryOn = options?.retryOn ?? isRetryableError;
|
|
48
|
+
let lastError;
|
|
49
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
50
|
+
try {
|
|
51
|
+
return await fn();
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
lastError = err;
|
|
55
|
+
if (attempt >= maxRetries || !retryOn(err)) {
|
|
56
|
+
throw err;
|
|
57
|
+
}
|
|
58
|
+
// Exponential backoff with jitter
|
|
59
|
+
const exponentialDelay = baseDelay * Math.pow(2, attempt);
|
|
60
|
+
const jitter = Math.random() * baseDelay;
|
|
61
|
+
const delay = Math.min(exponentialDelay + jitter, maxDelay);
|
|
62
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Unreachable but satisfies TypeScript
|
|
66
|
+
throw lastError;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type PublicClient, type WalletClient, type Chain, type Transport, type Account } from 'viem';
|
|
2
|
+
import { type SmartAccount } from 'viem/account-abstraction';
|
|
3
|
+
import { type SmartAccountClient as PermissionlessSmartAccountClient } from 'permissionless';
|
|
4
|
+
import { type PaymasterPolicy } from './paymaster.js';
|
|
5
|
+
/** SmartAccountClient type with concrete SmartAccount (not `SmartAccount | undefined`).
|
|
6
|
+
* This ensures sendTransaction() doesn't require explicit `account` parameter. */
|
|
7
|
+
export type AzethSmartAccountClient = PermissionlessSmartAccountClient<Transport, Chain, SmartAccount>;
|
|
8
|
+
export interface SmartAccountClientConfig {
|
|
9
|
+
publicClient: PublicClient<Transport, Chain>;
|
|
10
|
+
walletClient: WalletClient<Transport, Chain, Account>;
|
|
11
|
+
smartAccountAddress: `0x${string}`;
|
|
12
|
+
bundlerUrl?: string;
|
|
13
|
+
paymasterUrl?: string;
|
|
14
|
+
/** Client-side sponsorship policy for paymaster gas sponsorship.
|
|
15
|
+
* Only applies when paymasterUrl is configured. */
|
|
16
|
+
paymasterPolicy?: PaymasterPolicy;
|
|
17
|
+
/** Optional guardian co-signing key. When set, every UserOperation gets a
|
|
18
|
+
* 130-byte dual signature (owner 65 bytes + guardian 65 bytes), enabling
|
|
19
|
+
* operations that exceed standard spending limits. */
|
|
20
|
+
guardianKey?: `0x${string}`;
|
|
21
|
+
/** Azeth server URL. Used as bundler fallback on testnet — the server
|
|
22
|
+
* proxies bundler requests using its own PIMLICO_API_KEY so developers
|
|
23
|
+
* don't need their own key for getting started. */
|
|
24
|
+
serverUrl?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Create a viem SmartAccount implementation for an existing deployed AzethAccount.
|
|
28
|
+
*
|
|
29
|
+
* This wraps a deployed AzethAccount v12 smart account as a viem SmartAccount
|
|
30
|
+
* that can be used with permissionless's createSmartAccountClient to submit
|
|
31
|
+
* UserOperations through ERC-4337 EntryPoint v0.7.
|
|
32
|
+
*
|
|
33
|
+
* The signing flow matches GuardianModule expectations:
|
|
34
|
+
* - Computes getUserOperationHash (ERC-4337 standard)
|
|
35
|
+
* - Signs with walletClient.signMessage({ message: { raw: hash } })
|
|
36
|
+
* - This produces sign(keccak256("\x19Ethereum Signed Message:\n32" + userOpHash))
|
|
37
|
+
* - GuardianModule._splitSignature expects ECDSA owner sig as first 65 bytes
|
|
38
|
+
*/
|
|
39
|
+
export declare function createAzethSmartAccount(publicClient: PublicClient<Transport, Chain>, walletClient: WalletClient<Transport, Chain, Account>, smartAccountAddress: `0x${string}`, guardianKey?: `0x${string}`): Promise<SmartAccount>;
|
|
40
|
+
/**
|
|
41
|
+
* Create a permissionless SmartAccountClient for an AzethAccount.
|
|
42
|
+
*
|
|
43
|
+
* The SmartAccountClient handles the full ERC-4337 flow:
|
|
44
|
+
* 1. Encodes calls via account.encodeCalls()
|
|
45
|
+
* 2. Gets nonce from EntryPoint
|
|
46
|
+
* 3. Estimates gas via bundler
|
|
47
|
+
* 4. Signs UserOp via account.signUserOperation()
|
|
48
|
+
* 5. Submits to bundler via eth_sendUserOperation
|
|
49
|
+
* 6. Waits for receipt and returns transaction hash
|
|
50
|
+
*
|
|
51
|
+
* @param config - Configuration with clients, smart account address, and bundler URL
|
|
52
|
+
* @returns A SmartAccountClient that can be used for sendTransaction/writeContract
|
|
53
|
+
*/
|
|
54
|
+
export declare function createAzethSmartAccountClient(config: SmartAccountClientConfig): Promise<AzethSmartAccountClient>;
|
|
55
|
+
//# sourceMappingURL=userop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userop.d.ts","sourceRoot":"","sources":["../../src/utils/userop.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,SAAS,EACd,KAAK,OAAO,EAKb,MAAM,MAAM,CAAC;AAEd,OAAO,EAEL,KAAK,YAAY,EAIlB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAA4B,KAAK,kBAAkB,IAAI,gCAAgC,EAAE,MAAM,gBAAgB,CAAC;AAIvH,OAAO,EAA6B,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjF;mFACmF;AACnF,MAAM,MAAM,uBAAuB,GAAG,gCAAgC,CAAC,SAAS,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;AAEvG,MAAM,WAAW,wBAAwB;IACvC,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC7C,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IACtD,mBAAmB,EAAE,KAAK,MAAM,EAAE,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;wDACoD;IACpD,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;2DAEuD;IACvD,WAAW,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IAC5B;;wDAEoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,uBAAuB,CAC3C,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,EAC5C,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,EACrD,mBAAmB,EAAE,KAAK,MAAM,EAAE,EAClC,WAAW,CAAC,EAAE,KAAK,MAAM,EAAE,GAC1B,OAAO,CAAC,YAAY,CAAC,CAgIvB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,wBAAwB,GAC/B,OAAO,CAAC,uBAAuB,CAAC,CAyElC"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { encodeFunctionData, http, createNonceManager, } from 'viem';
|
|
2
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
3
|
+
import { toSmartAccount, entryPoint07Abi, entryPoint07Address, getUserOperationHash, } from 'viem/account-abstraction';
|
|
4
|
+
import { createSmartAccountClient } from 'permissionless';
|
|
5
|
+
import { AzethAccountAbi } from '@azeth/common/abis';
|
|
6
|
+
import { AzethError, SUPPORTED_CHAINS, getBundlerUrl, getPaymasterUrl, getServerBundlerUrl } from '@azeth/common';
|
|
7
|
+
import { encodeSimpleSingle, encodeSimpleBatch, encodeSingleExecution, encodeBatchExecution } from './execution.js';
|
|
8
|
+
import { createPaymasterMiddleware } from './paymaster.js';
|
|
9
|
+
/**
|
|
10
|
+
* Create a viem SmartAccount implementation for an existing deployed AzethAccount.
|
|
11
|
+
*
|
|
12
|
+
* This wraps a deployed AzethAccount v12 smart account as a viem SmartAccount
|
|
13
|
+
* that can be used with permissionless's createSmartAccountClient to submit
|
|
14
|
+
* UserOperations through ERC-4337 EntryPoint v0.7.
|
|
15
|
+
*
|
|
16
|
+
* The signing flow matches GuardianModule expectations:
|
|
17
|
+
* - Computes getUserOperationHash (ERC-4337 standard)
|
|
18
|
+
* - Signs with walletClient.signMessage({ message: { raw: hash } })
|
|
19
|
+
* - This produces sign(keccak256("\x19Ethereum Signed Message:\n32" + userOpHash))
|
|
20
|
+
* - GuardianModule._splitSignature expects ECDSA owner sig as first 65 bytes
|
|
21
|
+
*/
|
|
22
|
+
export async function createAzethSmartAccount(publicClient, walletClient, smartAccountAddress, guardianKey) {
|
|
23
|
+
const chainId = publicClient.chain?.id;
|
|
24
|
+
if (!chainId) {
|
|
25
|
+
throw new AzethError('Public client must have a chain configured', 'NETWORK_ERROR');
|
|
26
|
+
}
|
|
27
|
+
return toSmartAccount({
|
|
28
|
+
client: publicClient,
|
|
29
|
+
entryPoint: {
|
|
30
|
+
abi: entryPoint07Abi,
|
|
31
|
+
address: entryPoint07Address,
|
|
32
|
+
version: '0.7',
|
|
33
|
+
},
|
|
34
|
+
// Override viem's default time-based nonce key manager.
|
|
35
|
+
// viem defaults to Date.now() as the nonce key, which produces 192-bit
|
|
36
|
+
// timestamp keys (e.g., key=1771722560333). Our EntryPoint nonces live
|
|
37
|
+
// at key=0, so the SDK would sign a UserOp with nonce=(timestamp<<64|seq)
|
|
38
|
+
// while the bundler/EntryPoint expects nonce=(0<<64|seq) — causing AA24.
|
|
39
|
+
nonceKeyManager: createNonceManager({
|
|
40
|
+
source: {
|
|
41
|
+
get() { return 0; },
|
|
42
|
+
set() { },
|
|
43
|
+
},
|
|
44
|
+
}),
|
|
45
|
+
// Return the existing deployed account address
|
|
46
|
+
getAddress: async () => smartAccountAddress,
|
|
47
|
+
// Our account is already deployed — no factory needed
|
|
48
|
+
getFactoryArgs: async () => ({
|
|
49
|
+
factory: undefined,
|
|
50
|
+
factoryData: undefined,
|
|
51
|
+
}),
|
|
52
|
+
// Encode calls into AzethAccount.execute() callData
|
|
53
|
+
encodeCalls: async (calls) => {
|
|
54
|
+
if (calls.length === 0) {
|
|
55
|
+
throw new AzethError('At least one call is required', 'INVALID_INPUT');
|
|
56
|
+
}
|
|
57
|
+
if (calls.length === 1) {
|
|
58
|
+
const call = calls[0];
|
|
59
|
+
return encodeFunctionData({
|
|
60
|
+
abi: AzethAccountAbi,
|
|
61
|
+
functionName: 'execute',
|
|
62
|
+
args: [
|
|
63
|
+
encodeSimpleSingle(),
|
|
64
|
+
encodeSingleExecution(call.to, call.value ?? 0n, (call.data ?? '0x')),
|
|
65
|
+
],
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
// Batch execution: encode multiple calls into a single UserOp
|
|
69
|
+
return encodeFunctionData({
|
|
70
|
+
abi: AzethAccountAbi,
|
|
71
|
+
functionName: 'execute',
|
|
72
|
+
args: [
|
|
73
|
+
encodeSimpleBatch(),
|
|
74
|
+
encodeBatchExecution(calls.map(c => ({
|
|
75
|
+
target: c.to,
|
|
76
|
+
value: c.value ?? 0n,
|
|
77
|
+
data: (c.data ?? '0x'),
|
|
78
|
+
}))),
|
|
79
|
+
],
|
|
80
|
+
});
|
|
81
|
+
},
|
|
82
|
+
// Sign a personal message (EIP-191) via the owner EOA
|
|
83
|
+
signMessage: async ({ message }) => {
|
|
84
|
+
return walletClient.signMessage({ message });
|
|
85
|
+
},
|
|
86
|
+
// Sign a UserOperation: compute the ERC-4337 userOpHash and sign it
|
|
87
|
+
signUserOperation: async (userOperation) => {
|
|
88
|
+
const userOpForHash = {
|
|
89
|
+
...userOperation,
|
|
90
|
+
sender: userOperation.sender ?? smartAccountAddress,
|
|
91
|
+
};
|
|
92
|
+
const hash = getUserOperationHash({
|
|
93
|
+
chainId,
|
|
94
|
+
entryPointAddress: entryPoint07Address,
|
|
95
|
+
entryPointVersion: '0.7',
|
|
96
|
+
userOperation: userOpForHash,
|
|
97
|
+
});
|
|
98
|
+
// Sign with EIP-191 personal sign: this produces
|
|
99
|
+
// sign(keccak256("\x19Ethereum Signed Message:\n32" + hash))
|
|
100
|
+
// which matches GuardianModule's ecrecover(hash.toEthSignedMessageHash(), v, r, s)
|
|
101
|
+
const ownerSig = await walletClient.signMessage({ message: { raw: hash } });
|
|
102
|
+
// Guardian co-signature: append 65-byte guardian sig to produce 130-byte dual signature
|
|
103
|
+
if (guardianKey) {
|
|
104
|
+
const guardianAccount = privateKeyToAccount(guardianKey);
|
|
105
|
+
const guardianSig = await guardianAccount.signMessage({ message: { raw: hash } });
|
|
106
|
+
// Concatenate: ownerSig (0x + 128 hex chars) + guardianSig (128 hex chars, no 0x prefix)
|
|
107
|
+
return (ownerSig + guardianSig.slice(2));
|
|
108
|
+
}
|
|
109
|
+
return ownerSig;
|
|
110
|
+
},
|
|
111
|
+
// Sign typed data via the owner EOA
|
|
112
|
+
signTypedData: async (typedData) => {
|
|
113
|
+
return walletClient.signTypedData(typedData);
|
|
114
|
+
},
|
|
115
|
+
// 65-byte dummy signature for gas estimation.
|
|
116
|
+
// Must be a valid ECDSA signature (r=1, s=1, v=27) so tryRecover succeeds
|
|
117
|
+
// and the full validateUserOp code path executes (guardrails, oracle, etc.).
|
|
118
|
+
// An all-0xFF stub triggers ECDSAInvalidSignatureS, taking a short path that
|
|
119
|
+
// causes the bundler to underestimate verificationGasLimit (AA26).
|
|
120
|
+
getStubSignature: async () => {
|
|
121
|
+
const stub65 = ('0x' + '00'.repeat(31) + '01' + '00'.repeat(31) + '01' + '1b');
|
|
122
|
+
if (guardianKey) {
|
|
123
|
+
// 130-byte stub: two valid ECDSA dummy signatures for owner + guardian
|
|
124
|
+
return (stub65 + stub65.slice(2));
|
|
125
|
+
}
|
|
126
|
+
return stub65;
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Create a permissionless SmartAccountClient for an AzethAccount.
|
|
132
|
+
*
|
|
133
|
+
* The SmartAccountClient handles the full ERC-4337 flow:
|
|
134
|
+
* 1. Encodes calls via account.encodeCalls()
|
|
135
|
+
* 2. Gets nonce from EntryPoint
|
|
136
|
+
* 3. Estimates gas via bundler
|
|
137
|
+
* 4. Signs UserOp via account.signUserOperation()
|
|
138
|
+
* 5. Submits to bundler via eth_sendUserOperation
|
|
139
|
+
* 6. Waits for receipt and returns transaction hash
|
|
140
|
+
*
|
|
141
|
+
* @param config - Configuration with clients, smart account address, and bundler URL
|
|
142
|
+
* @returns A SmartAccountClient that can be used for sendTransaction/writeContract
|
|
143
|
+
*/
|
|
144
|
+
export async function createAzethSmartAccountClient(config) {
|
|
145
|
+
const { publicClient, walletClient, smartAccountAddress, bundlerUrl, paymasterPolicy } = config;
|
|
146
|
+
const chainId = publicClient.chain?.id;
|
|
147
|
+
if (!chainId) {
|
|
148
|
+
throw new AzethError('Public client must have a chain configured', 'NETWORK_ERROR');
|
|
149
|
+
}
|
|
150
|
+
// Resolve chain name from chain ID for URL resolution
|
|
151
|
+
const chainName = Object.entries(SUPPORTED_CHAINS)
|
|
152
|
+
.find(([, c]) => c.id === chainId)?.[0];
|
|
153
|
+
// Resolve bundler URL: explicit config > env var > chain base URL + API key > error
|
|
154
|
+
let resolvedBundlerUrl = bundlerUrl;
|
|
155
|
+
if (!resolvedBundlerUrl) {
|
|
156
|
+
if (chainName) {
|
|
157
|
+
const apiKey = typeof globalThis.process !== 'undefined'
|
|
158
|
+
? globalThis.process.env?.['PIMLICO_API_KEY']
|
|
159
|
+
: undefined;
|
|
160
|
+
resolvedBundlerUrl = getBundlerUrl(chainName, apiKey);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// Fallback: use Azeth server bundler proxy (testnet gas sponsorship)
|
|
164
|
+
if (!resolvedBundlerUrl && config.serverUrl) {
|
|
165
|
+
resolvedBundlerUrl = getServerBundlerUrl(config.serverUrl);
|
|
166
|
+
}
|
|
167
|
+
if (!resolvedBundlerUrl) {
|
|
168
|
+
throw new AzethError('bundlerUrl is required for UserOperation submission. ' +
|
|
169
|
+
'Set PIMLICO_API_KEY or AZETH_BUNDLER_URL env var, or pass bundlerUrl in AzethKitConfig. ' +
|
|
170
|
+
'Get a free key at https://dashboard.pimlico.io or https://portal.cdp.coinbase.com.', 'INVALID_INPUT', { chainId });
|
|
171
|
+
}
|
|
172
|
+
// Resolve paymaster URL: explicit config > env var > chain default (same as bundler for Pimlico)
|
|
173
|
+
let resolvedPaymasterUrl = config.paymasterUrl;
|
|
174
|
+
if (!resolvedPaymasterUrl) {
|
|
175
|
+
resolvedPaymasterUrl = typeof globalThis.process !== 'undefined'
|
|
176
|
+
? globalThis.process.env?.['AZETH_PAYMASTER_URL']
|
|
177
|
+
: undefined;
|
|
178
|
+
if (!resolvedPaymasterUrl && chainName) {
|
|
179
|
+
const apiKey = typeof globalThis.process !== 'undefined'
|
|
180
|
+
? globalThis.process.env?.['PIMLICO_API_KEY']
|
|
181
|
+
: undefined;
|
|
182
|
+
resolvedPaymasterUrl = getPaymasterUrl(chainName, apiKey);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const smartAccount = await createAzethSmartAccount(publicClient, walletClient, smartAccountAddress, config.guardianKey);
|
|
186
|
+
// Build SmartAccountClient config with optional paymaster
|
|
187
|
+
const clientConfig = {
|
|
188
|
+
account: smartAccount,
|
|
189
|
+
chain: publicClient.chain,
|
|
190
|
+
bundlerTransport: http(resolvedBundlerUrl),
|
|
191
|
+
client: publicClient,
|
|
192
|
+
};
|
|
193
|
+
// Wire paymaster middleware when URL is available.
|
|
194
|
+
// The middleware handles graceful fallback: if the paymaster rejects or is
|
|
195
|
+
// unreachable, the UserOp falls back to self-paid gas (no crash).
|
|
196
|
+
if (resolvedPaymasterUrl) {
|
|
197
|
+
clientConfig.paymaster = createPaymasterMiddleware(resolvedPaymasterUrl, paymasterPolicy);
|
|
198
|
+
}
|
|
199
|
+
return createSmartAccountClient(clientConfig);
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=userop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userop.js","sourceRoot":"","sources":["../../src/utils/userop.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Validate that a string is a valid Ethereum address (0x + 40 hex chars).
|
|
2
|
+
* L-12 fix (Audit #8): Also rejects the zero address to prevent accidental fund burns. */
|
|
3
|
+
export declare function validateAddress(address: string, fieldName: string): void;
|
|
4
|
+
/** Validate that a URL is well-formed HTTP(S). Optionally require HTTPS. */
|
|
5
|
+
export declare function validateUrl(url: string, fieldName: string, requireHttps?: boolean): void;
|
|
6
|
+
/** Validate that a bigint amount is positive */
|
|
7
|
+
export declare function validatePositiveAmount(amount: bigint, fieldName: string): void;
|
|
8
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAEA;2FAC2F;AAC3F,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAexE;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,UAAQ,GAAG,IAAI,CAatF;AAED,gDAAgD;AAChD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAQ9E"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { AzethError } from '@azeth/common';
|
|
2
|
+
/** Validate that a string is a valid Ethereum address (0x + 40 hex chars).
|
|
3
|
+
* L-12 fix (Audit #8): Also rejects the zero address to prevent accidental fund burns. */
|
|
4
|
+
export function validateAddress(address, fieldName) {
|
|
5
|
+
if (!/^0x[a-fA-F0-9]{40}$/.test(address)) {
|
|
6
|
+
throw new AzethError('Invalid Ethereum address format', 'INVALID_INPUT', { field: fieldName });
|
|
7
|
+
}
|
|
8
|
+
if (address === '0x0000000000000000000000000000000000000000') {
|
|
9
|
+
throw new AzethError('Cannot use the zero address', 'INVALID_INPUT', { field: fieldName });
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/** Validate that a URL is well-formed HTTP(S). Optionally require HTTPS. */
|
|
13
|
+
export function validateUrl(url, fieldName, requireHttps = false) {
|
|
14
|
+
try {
|
|
15
|
+
const parsed = new URL(url);
|
|
16
|
+
if (requireHttps && parsed.protocol !== 'https:') {
|
|
17
|
+
throw new AzethError('URL must use HTTPS', 'INVALID_INPUT', { field: fieldName });
|
|
18
|
+
}
|
|
19
|
+
if (!['http:', 'https:'].includes(parsed.protocol)) {
|
|
20
|
+
throw new AzethError('URL must use HTTP or HTTPS', 'INVALID_INPUT', { field: fieldName });
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
if (e instanceof AzethError)
|
|
25
|
+
throw e;
|
|
26
|
+
throw new AzethError('Invalid URL format', 'INVALID_INPUT', { field: fieldName });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** Validate that a bigint amount is positive */
|
|
30
|
+
export function validatePositiveAmount(amount, fieldName) {
|
|
31
|
+
if (amount <= 0n) {
|
|
32
|
+
throw new AzethError(`Invalid ${fieldName}: must be greater than 0`, 'INVALID_INPUT', { field: fieldName, value: amount.toString() });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C;2FAC2F;AAC3F,MAAM,UAAU,eAAe,CAAC,OAAe,EAAE,SAAiB;IAChE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,UAAU,CAClB,iCAAiC,EACjC,eAAe,EACf,EAAE,KAAK,EAAE,SAAS,EAAE,CACrB,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,KAAK,4CAA4C,EAAE,CAAC;QAC7D,MAAM,IAAI,UAAU,CAClB,6BAA6B,EAC7B,eAAe,EACf,EAAE,KAAK,EAAE,SAAS,EAAE,CACrB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,SAAiB,EAAE,YAAY,GAAG,KAAK;IAC9E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,YAAY,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjD,MAAM,IAAI,UAAU,CAAC,oBAAoB,EAAE,eAAe,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,UAAU,CAAC,4BAA4B,EAAE,eAAe,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,UAAU;YAAE,MAAM,CAAC,CAAC;QACrC,MAAM,IAAI,UAAU,CAAC,oBAAoB,EAAE,eAAe,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACpF,CAAC;AACH,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,sBAAsB,CAAC,MAAc,EAAE,SAAiB;IACtE,IAAI,MAAM,IAAI,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,UAAU,CAClB,WAAW,SAAS,0BAA0B,EAC9C,eAAe,EACf,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,CAC/C,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@azeth/sdk",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "TypeScript SDK for the Azeth trust infrastructure — smart accounts, x402 payments, reputation, and service discovery",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/azeth-protocol/sdk.git"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://azeth.ai",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"azeth",
|
|
14
|
+
"sdk",
|
|
15
|
+
"machine-economy",
|
|
16
|
+
"trust-registry",
|
|
17
|
+
"erc-4337",
|
|
18
|
+
"smart-accounts",
|
|
19
|
+
"x402",
|
|
20
|
+
"payments",
|
|
21
|
+
"reputation",
|
|
22
|
+
"xmtp"
|
|
23
|
+
],
|
|
24
|
+
"main": "dist/index.js",
|
|
25
|
+
"types": "dist/index.d.ts",
|
|
26
|
+
"files": [
|
|
27
|
+
"dist/",
|
|
28
|
+
"README.md",
|
|
29
|
+
"LICENSE"
|
|
30
|
+
],
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@azeth/common": "^0.2.0",
|
|
33
|
+
"@x402/core": "^2.4.0",
|
|
34
|
+
"@x402/extensions": "^2.4.0",
|
|
35
|
+
"@xmtp/agent-sdk": "^2.2.0",
|
|
36
|
+
"permissionless": "^0.3.4",
|
|
37
|
+
"viem": "^2.21.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@stryker-mutator/core": "^8.6.0",
|
|
41
|
+
"@stryker-mutator/vitest-runner": "^8.6.0",
|
|
42
|
+
"@types/node": "^22.0.0",
|
|
43
|
+
"typescript": "^5.7.0",
|
|
44
|
+
"vitest": "^2.1.0",
|
|
45
|
+
"@changesets/cli": "^2.27.0"
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=20.0.0"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsc --project tsconfig.json",
|
|
55
|
+
"dev": "tsc --watch",
|
|
56
|
+
"test": "vitest run",
|
|
57
|
+
"test:watch": "vitest",
|
|
58
|
+
"typecheck": "tsc --noEmit",
|
|
59
|
+
"clean": "rm -rf dist",
|
|
60
|
+
"test:mutation": "npx stryker run",
|
|
61
|
+
"release": "pnpm build && changeset publish"
|
|
62
|
+
}
|
|
63
|
+
}
|