@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.
Files changed (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +139 -0
  3. package/dist/account/balance.d.ts +41 -0
  4. package/dist/account/balance.d.ts.map +1 -0
  5. package/dist/account/balance.js +264 -0
  6. package/dist/account/balance.js.map +1 -0
  7. package/dist/account/create.d.ts +27 -0
  8. package/dist/account/create.d.ts.map +1 -0
  9. package/dist/account/create.js +116 -0
  10. package/dist/account/create.js.map +1 -0
  11. package/dist/account/deposit.d.ts +34 -0
  12. package/dist/account/deposit.d.ts.map +1 -0
  13. package/dist/account/deposit.js +88 -0
  14. package/dist/account/deposit.js.map +1 -0
  15. package/dist/account/guardian-approval.d.ts +111 -0
  16. package/dist/account/guardian-approval.d.ts.map +1 -0
  17. package/dist/account/guardian-approval.js +223 -0
  18. package/dist/account/guardian-approval.js.map +1 -0
  19. package/dist/account/guardian.d.ts +27 -0
  20. package/dist/account/guardian.d.ts.map +1 -0
  21. package/dist/account/guardian.js +67 -0
  22. package/dist/account/guardian.js.map +1 -0
  23. package/dist/account/history.d.ts +22 -0
  24. package/dist/account/history.d.ts.map +1 -0
  25. package/dist/account/history.js +144 -0
  26. package/dist/account/history.js.map +1 -0
  27. package/dist/account/transfer.d.ts +28 -0
  28. package/dist/account/transfer.d.ts.map +1 -0
  29. package/dist/account/transfer.js +137 -0
  30. package/dist/account/transfer.js.map +1 -0
  31. package/dist/auth/erc8128.d.ts +14 -0
  32. package/dist/auth/erc8128.d.ts.map +1 -0
  33. package/dist/auth/erc8128.js +92 -0
  34. package/dist/auth/erc8128.js.map +1 -0
  35. package/dist/client.d.ts +394 -0
  36. package/dist/client.d.ts.map +1 -0
  37. package/dist/client.js +970 -0
  38. package/dist/client.js.map +1 -0
  39. package/dist/events/emitter.d.ts +96 -0
  40. package/dist/events/emitter.d.ts.map +1 -0
  41. package/dist/events/emitter.js +90 -0
  42. package/dist/events/emitter.js.map +1 -0
  43. package/dist/index.d.ts +29 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +33 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/messaging/message-router.d.ts +69 -0
  48. package/dist/messaging/message-router.d.ts.map +1 -0
  49. package/dist/messaging/message-router.js +307 -0
  50. package/dist/messaging/message-router.js.map +1 -0
  51. package/dist/messaging/rate-limiter.d.ts +31 -0
  52. package/dist/messaging/rate-limiter.d.ts.map +1 -0
  53. package/dist/messaging/rate-limiter.js +74 -0
  54. package/dist/messaging/rate-limiter.js.map +1 -0
  55. package/dist/messaging/xmtp.d.ts +144 -0
  56. package/dist/messaging/xmtp.d.ts.map +1 -0
  57. package/dist/messaging/xmtp.js +473 -0
  58. package/dist/messaging/xmtp.js.map +1 -0
  59. package/dist/payments/agreements.d.ts +87 -0
  60. package/dist/payments/agreements.d.ts.map +1 -0
  61. package/dist/payments/agreements.js +337 -0
  62. package/dist/payments/agreements.js.map +1 -0
  63. package/dist/payments/budget.d.ts +118 -0
  64. package/dist/payments/budget.d.ts.map +1 -0
  65. package/dist/payments/budget.js +176 -0
  66. package/dist/payments/budget.js.map +1 -0
  67. package/dist/payments/smart-fetch.d.ts +65 -0
  68. package/dist/payments/smart-fetch.d.ts.map +1 -0
  69. package/dist/payments/smart-fetch.js +115 -0
  70. package/dist/payments/smart-fetch.js.map +1 -0
  71. package/dist/payments/x402.d.ts +89 -0
  72. package/dist/payments/x402.d.ts.map +1 -0
  73. package/dist/payments/x402.js +620 -0
  74. package/dist/payments/x402.js.map +1 -0
  75. package/dist/registry/discover.d.ts +43 -0
  76. package/dist/registry/discover.d.ts.map +1 -0
  77. package/dist/registry/discover.js +272 -0
  78. package/dist/registry/discover.js.map +1 -0
  79. package/dist/registry/register.d.ts +44 -0
  80. package/dist/registry/register.d.ts.map +1 -0
  81. package/dist/registry/register.js +126 -0
  82. package/dist/registry/register.js.map +1 -0
  83. package/dist/reputation/opinion.d.ts +52 -0
  84. package/dist/reputation/opinion.d.ts.map +1 -0
  85. package/dist/reputation/opinion.js +198 -0
  86. package/dist/reputation/opinion.js.map +1 -0
  87. package/dist/utils/addresses.d.ts +6 -0
  88. package/dist/utils/addresses.d.ts.map +1 -0
  89. package/dist/utils/addresses.js +53 -0
  90. package/dist/utils/addresses.js.map +1 -0
  91. package/dist/utils/errors.d.ts +23 -0
  92. package/dist/utils/errors.d.ts.map +1 -0
  93. package/dist/utils/errors.js +188 -0
  94. package/dist/utils/errors.js.map +1 -0
  95. package/dist/utils/execution.d.ts +20 -0
  96. package/dist/utils/execution.d.ts.map +1 -0
  97. package/dist/utils/execution.js +28 -0
  98. package/dist/utils/execution.js.map +1 -0
  99. package/dist/utils/paymaster.d.ts +35 -0
  100. package/dist/utils/paymaster.d.ts.map +1 -0
  101. package/dist/utils/paymaster.js +115 -0
  102. package/dist/utils/paymaster.js.map +1 -0
  103. package/dist/utils/retry.d.ts +19 -0
  104. package/dist/utils/retry.d.ts.map +1 -0
  105. package/dist/utils/retry.js +68 -0
  106. package/dist/utils/retry.js.map +1 -0
  107. package/dist/utils/userop.d.ts +55 -0
  108. package/dist/utils/userop.d.ts.map +1 -0
  109. package/dist/utils/userop.js +201 -0
  110. package/dist/utils/userop.js.map +1 -0
  111. package/dist/utils/validation.d.ts +8 -0
  112. package/dist/utils/validation.d.ts.map +1 -0
  113. package/dist/utils/validation.js +35 -0
  114. package/dist/utils/validation.js.map +1 -0
  115. package/package.json +63 -0
@@ -0,0 +1,144 @@
1
+ import { withRetry } from '../utils/retry.js';
2
+ /** Pad an address to a 32-byte hex topic for event log filtering */
3
+ function addressToTopic(addr) {
4
+ return `0x000000000000000000000000${addr.slice(2).toLowerCase()}`;
5
+ }
6
+ /** Get transaction history for an account
7
+ * Tries server API first, then falls back to on-chain TransferRecorded events
8
+ * from the ReputationModule (last ~1000 blocks).
9
+ */
10
+ export async function getHistory(publicClient, account, serverUrl, params, reputationModuleAddress, tokenAddresses) {
11
+ // If server URL is provided, try the indexed API (fall back gracefully if unreachable)
12
+ if (serverUrl) {
13
+ const queryParams = new URLSearchParams();
14
+ queryParams.set('address', account);
15
+ if (params?.limit)
16
+ queryParams.set('limit', params.limit.toString());
17
+ if (params?.offset)
18
+ queryParams.set('offset', params.offset.toString());
19
+ try {
20
+ const response = await withRetry(() => fetch(`${serverUrl}/api/v1/history?${queryParams}`));
21
+ if (response.ok) {
22
+ return await response.json();
23
+ }
24
+ // Non-OK response — fall through to on-chain fallback
25
+ }
26
+ catch {
27
+ // Server unreachable — fall through to on-chain fallback
28
+ }
29
+ }
30
+ // On-chain fallback: query TransferRecorded events from ReputationModule
31
+ if (!reputationModuleAddress)
32
+ return [];
33
+ try {
34
+ const currentBlock = await publicClient.getBlockNumber();
35
+ const fromBlock = params?.fromBlock ?? (currentBlock > 50000n ? currentBlock - 50000n : 0n);
36
+ const limit = params?.limit ?? 50;
37
+ const accountTopic = addressToTopic(account);
38
+ // Query outgoing (from=account) and incoming (to=account) in parallel
39
+ const [outgoing, incoming] = await Promise.all([
40
+ publicClient.getLogs({
41
+ address: reputationModuleAddress,
42
+ event: {
43
+ type: 'event',
44
+ name: 'TransferRecorded',
45
+ inputs: [
46
+ { name: 'from', type: 'address', indexed: true },
47
+ { name: 'to', type: 'address', indexed: true },
48
+ { name: 'token', type: 'address', indexed: true },
49
+ { name: 'amount', type: 'uint256', indexed: false },
50
+ ],
51
+ },
52
+ args: { from: account },
53
+ fromBlock,
54
+ toBlock: currentBlock,
55
+ }).catch(() => []),
56
+ publicClient.getLogs({
57
+ address: reputationModuleAddress,
58
+ event: {
59
+ type: 'event',
60
+ name: 'TransferRecorded',
61
+ inputs: [
62
+ { name: 'from', type: 'address', indexed: true },
63
+ { name: 'to', type: 'address', indexed: true },
64
+ { name: 'token', type: 'address', indexed: true },
65
+ { name: 'amount', type: 'uint256', indexed: false },
66
+ ],
67
+ },
68
+ args: { to: account },
69
+ fromBlock,
70
+ toBlock: currentBlock,
71
+ }).catch(() => []),
72
+ ]);
73
+ // Query standard ERC-20 Transfer events for incoming deposits.
74
+ // Deposits via direct ERC-20 transfer() bypass the ReputationModule Hook,
75
+ // so no TransferRecorded events are emitted — we must query Transfer events directly.
76
+ const validTokens = (tokenAddresses ?? []).filter(Boolean);
77
+ const depositLogs = validTokens.length > 0
78
+ ? (await Promise.all(validTokens.map(tokenAddr => publicClient.getLogs({
79
+ address: tokenAddr,
80
+ event: {
81
+ type: 'event',
82
+ name: 'Transfer',
83
+ inputs: [
84
+ { name: 'from', type: 'address', indexed: true },
85
+ { name: 'to', type: 'address', indexed: true },
86
+ { name: 'value', type: 'uint256', indexed: false },
87
+ ],
88
+ },
89
+ args: { to: account },
90
+ fromBlock,
91
+ toBlock: currentBlock,
92
+ }).catch(() => [])))).flat()
93
+ : [];
94
+ // Merge, deduplicate by txHash, and sort by blockNumber descending
95
+ const allLogs = [...outgoing, ...incoming, ...depositLogs];
96
+ const seen = new Set();
97
+ const records = [];
98
+ for (const log of allLogs) {
99
+ const txHash = log.transactionHash;
100
+ if (!txHash || seen.has(txHash))
101
+ continue;
102
+ seen.add(txHash);
103
+ const args = log.args;
104
+ const from = args.from;
105
+ const to = args.to;
106
+ // TransferRecorded has 'token' and 'amount'; ERC-20 Transfer has 'value' and log.address is the token
107
+ const token = args.token ?? (args.value !== undefined ? log.address : null);
108
+ const amount = args.amount ?? args.value;
109
+ records.push({
110
+ hash: txHash,
111
+ from: from ?? account,
112
+ to: to ?? null,
113
+ value: amount ?? 0n,
114
+ token: token ?? null,
115
+ blockNumber: log.blockNumber ?? 0n,
116
+ timestamp: 0,
117
+ });
118
+ }
119
+ // Sort by blockNumber descending (most recent first) and apply limit
120
+ records.sort((a, b) => Number(b.blockNumber - a.blockNumber));
121
+ const sliced = records.slice(0, limit);
122
+ // Batch-fetch block timestamps for unique block numbers
123
+ const uniqueBlocks = [...new Set(sliced.map(r => r.blockNumber))];
124
+ const blockTimestamps = new Map();
125
+ await Promise.all(uniqueBlocks.map(async (blockNumber) => {
126
+ try {
127
+ const block = await publicClient.getBlock({ blockNumber });
128
+ blockTimestamps.set(blockNumber, Number(block.timestamp));
129
+ }
130
+ catch {
131
+ // If block fetch fails, leave timestamp as 0
132
+ }
133
+ }));
134
+ for (const record of sliced) {
135
+ record.timestamp = blockTimestamps.get(record.blockNumber) ?? 0;
136
+ }
137
+ return sliced;
138
+ }
139
+ catch {
140
+ // On-chain fallback failed — return empty
141
+ return [];
142
+ }
143
+ }
144
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/account/history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type PublicClient, type Chain, type Transport } from 'viem';
2
+ import { type AzethContractAddresses } from '@azeth/common';
3
+ import type { AzethSmartAccountClient } from '../utils/userop.js';
4
+ export interface TransferParams {
5
+ to: `0x${string}`;
6
+ token?: `0x${string}`;
7
+ amount: bigint;
8
+ }
9
+ export interface TransferResult {
10
+ txHash: `0x${string}`;
11
+ from: `0x${string}`;
12
+ to: `0x${string}`;
13
+ amount: bigint;
14
+ token: `0x${string}` | 'ETH';
15
+ }
16
+ /** Transfer ETH or ERC-20 tokens via the smart account using ERC-4337 UserOperations.
17
+ *
18
+ * The SmartAccountClient builds a UserOperation that routes through EntryPoint v0.7,
19
+ * which calls executeUserOp() on the AzethAccount. This is the ONLY authorized path
20
+ * for state-changing operations on AzethAccount v12.
21
+ *
22
+ * When publicClient and addresses are provided, a pre-flight guardrail check is
23
+ * performed via GuardianModule.checkOperation() to catch spending limit / whitelist
24
+ * failures with descriptive errors instead of the opaque "AA24 signature error".
25
+ *
26
+ * M-12 fix (Audit #8): Rejects zero-amount transfers at the raw function level. */
27
+ export declare function transfer(smartAccountClient: AzethSmartAccountClient, smartAccount: `0x${string}`, params: TransferParams, publicClient?: PublicClient<Transport, Chain>, addresses?: AzethContractAddresses): Promise<TransferResult>;
28
+ //# sourceMappingURL=transfer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer.d.ts","sourceRoot":"","sources":["../../src/account/transfer.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,SAAS,EACf,MAAM,MAAM,CAAC;AACd,OAAO,EAAiC,KAAK,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAG3F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAElE,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,KAAK,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IACtB,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;IACpB,EAAE,EAAE,KAAK,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,MAAM,EAAE,GAAG,KAAK,CAAC;CAC9B;AAoFD;;;;;;;;;;oFAUoF;AACpF,wBAAsB,QAAQ,CAC5B,kBAAkB,EAAE,uBAAuB,EAC3C,YAAY,EAAE,KAAK,MAAM,EAAE,EAC3B,MAAM,EAAE,cAAc,EACtB,YAAY,CAAC,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,EAC7C,SAAS,CAAC,EAAE,sBAAsB,GACjC,OAAO,CAAC,cAAc,CAAC,CAyDzB"}
@@ -0,0 +1,137 @@
1
+ import { erc20Abi, encodeFunctionData, } from 'viem';
2
+ import { AzethError, formatTokenAmount } from '@azeth/common';
3
+ import { GuardianModuleAbi } from '@azeth/common/abis';
4
+ import { requireAddress } from '../utils/addresses.js';
5
+ /** Reason enum values matching GuardianModule.ValidationReason order */
6
+ const VALIDATION_REASON_NAMES = [
7
+ 'OK',
8
+ 'ACCOUNT_NOT_INITIALIZED',
9
+ 'EXCEEDS_TX_LIMIT',
10
+ 'EXCEEDS_DAILY_LIMIT',
11
+ 'TARGET_NOT_WHITELISTED',
12
+ 'ORACLE_STALE',
13
+ 'GUARDIAN_REQUIRED',
14
+ ];
15
+ /** Format a bigint 18-decimal USD value for human-readable error messages */
16
+ function formatUSD(value18) {
17
+ return `$${formatTokenAmount(value18, 18, 2)}`;
18
+ }
19
+ /** Pre-flight guardrail check via GuardianModule.checkOperation().
20
+ *
21
+ * Calls the on-chain view function to get structured validation reasons before
22
+ * submitting a UserOp that would fail with the opaque "AA24 signature error".
23
+ *
24
+ * @throws AzethError('GUARDIAN_REJECTED') with human-readable details */
25
+ async function preflightCheck(publicClient, addresses, smartAccount, params) {
26
+ const guardianAddress = requireAddress(addresses, 'guardianModule');
27
+ // Map transfer params to checkOperation params:
28
+ // ETH: target=recipient, value=amount, token=address(0)
29
+ // ERC-20: target=tokenContract, value=amount, token=tokenContract
30
+ const target = params.token ?? params.to;
31
+ const token = params.token ?? '0x0000000000000000000000000000000000000000';
32
+ const [reason, details] = await publicClient.readContract({
33
+ address: guardianAddress,
34
+ abi: GuardianModuleAbi,
35
+ functionName: 'checkOperation',
36
+ args: [smartAccount, target, params.amount, token],
37
+ });
38
+ if (reason === 0)
39
+ return; // OK
40
+ const reasonName = VALIDATION_REASON_NAMES[reason] ?? 'UNKNOWN';
41
+ const errorDetails = {
42
+ reason: reasonName,
43
+ usdValue: formatUSD(details.usdValue),
44
+ dailySpentUSD: formatUSD(details.dailySpentUSD),
45
+ maxTxAmountUSD: formatUSD(details.maxTxAmountUSD),
46
+ dailySpendLimitUSD: formatUSD(details.dailySpendLimitUSD),
47
+ };
48
+ let message;
49
+ switch (reason) {
50
+ case 1: // ACCOUNT_NOT_INITIALIZED
51
+ message = `Smart account ${smartAccount} is not initialized with GuardianModule`;
52
+ break;
53
+ case 2: // EXCEEDS_TX_LIMIT
54
+ message = `Transfer of ${formatUSD(details.usdValue)} exceeds per-transaction limit of ${formatUSD(details.maxTxAmountUSD)}`;
55
+ break;
56
+ case 3: // EXCEEDS_DAILY_LIMIT
57
+ message = `Transfer of ${formatUSD(details.usdValue)} would push daily spend to ${formatUSD(details.dailySpentUSD + details.usdValue)}, exceeding daily limit of ${formatUSD(details.dailySpendLimitUSD)}`;
58
+ break;
59
+ case 4: // TARGET_NOT_WHITELISTED
60
+ message = `Target ${target} is not in the token or protocol whitelist. Add it via setTokenWhitelist() or setProtocolWhitelist()`;
61
+ break;
62
+ case 5: // ORACLE_STALE
63
+ message = `Price oracle is stale — guardian co-signature required for this transfer`;
64
+ break;
65
+ case 6: // GUARDIAN_REQUIRED
66
+ message = `Guardian co-signature required for this operation`;
67
+ break;
68
+ default:
69
+ message = `Guardian validation failed (reason ${reason})`;
70
+ }
71
+ throw new AzethError(message, 'GUARDIAN_REJECTED', errorDetails);
72
+ }
73
+ /** Transfer ETH or ERC-20 tokens via the smart account using ERC-4337 UserOperations.
74
+ *
75
+ * The SmartAccountClient builds a UserOperation that routes through EntryPoint v0.7,
76
+ * which calls executeUserOp() on the AzethAccount. This is the ONLY authorized path
77
+ * for state-changing operations on AzethAccount v12.
78
+ *
79
+ * When publicClient and addresses are provided, a pre-flight guardrail check is
80
+ * performed via GuardianModule.checkOperation() to catch spending limit / whitelist
81
+ * failures with descriptive errors instead of the opaque "AA24 signature error".
82
+ *
83
+ * M-12 fix (Audit #8): Rejects zero-amount transfers at the raw function level. */
84
+ export async function transfer(smartAccountClient, smartAccount, params, publicClient, addresses) {
85
+ // M-12 fix (Audit #8): Block negative amounts (bigint can go negative).
86
+ // AUDIT-FIX: Also reject zero-amount transfers — they waste gas on a no-op.
87
+ if (params.amount <= 0n) {
88
+ throw new AzethError('Transfer amount must be greater than zero', 'INVALID_INPUT', { field: 'amount' });
89
+ }
90
+ // Pre-flight guardrail check: catch spending limit / whitelist failures early
91
+ // with descriptive errors instead of opaque "AA24 signature error".
92
+ if (publicClient && addresses) {
93
+ await preflightCheck(publicClient, addresses, smartAccount, params);
94
+ }
95
+ let txHash;
96
+ try {
97
+ if (!params.token) {
98
+ // ETH transfer via UserOp: sendTransaction encodes via account.encodeCalls()
99
+ // which wraps in AzethAccount.execute(mode, encodeSingle(to, amount, "0x"))
100
+ txHash = await smartAccountClient.sendTransaction({
101
+ to: params.to,
102
+ value: params.amount,
103
+ data: '0x',
104
+ });
105
+ }
106
+ else {
107
+ // ERC-20 transfer via UserOp: encode the ERC-20 transfer call,
108
+ // then sendTransaction wraps in execute(mode, encodeSingle(token, 0, data))
109
+ const data = encodeFunctionData({
110
+ abi: erc20Abi,
111
+ functionName: 'transfer',
112
+ args: [params.to, params.amount],
113
+ });
114
+ txHash = await smartAccountClient.sendTransaction({
115
+ to: params.token,
116
+ value: 0n,
117
+ data,
118
+ });
119
+ }
120
+ }
121
+ catch (err) {
122
+ if (err instanceof AzethError)
123
+ throw err;
124
+ const message = err instanceof Error ? err.message : 'Transfer failed';
125
+ const isInsufficientFunds = message.toLowerCase().includes('insufficient') ||
126
+ message.toLowerCase().includes('exceeds balance');
127
+ throw new AzethError(message, isInsufficientFunds ? 'INSUFFICIENT_BALANCE' : 'CONTRACT_ERROR', { originalError: err instanceof Error ? err.name : undefined });
128
+ }
129
+ return {
130
+ txHash,
131
+ from: smartAccount,
132
+ to: params.to,
133
+ amount: params.amount,
134
+ token: params.token ?? 'ETH',
135
+ };
136
+ }
137
+ //# sourceMappingURL=transfer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer.js","sourceRoot":"","sources":["../../src/account/transfer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type WalletClient, type Chain, type Transport, type Account } from 'viem';
2
+ export interface SignedRequest {
3
+ signature: `0x${string}`;
4
+ nonce: string;
5
+ created: number;
6
+ keyid: `0x${string}`;
7
+ }
8
+ /** Sign an HTTP request with ERC-8128 */
9
+ export declare function signRequest(walletClient: WalletClient<Transport, Chain, Account>, signer: `0x${string}`, method: string, url: string, body?: string): Promise<SignedRequest>;
10
+ /** Build the ERC-8128 Authorization header value */
11
+ export declare function buildAuthHeader(signed: SignedRequest): string;
12
+ /** Create a fetch wrapper that automatically adds ERC-8128 auth headers */
13
+ export declare function createSignedFetch(walletClient: WalletClient<Transport, Chain, Account>, signer: `0x${string}`): typeof fetch;
14
+ //# sourceMappingURL=erc8128.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"erc8128.d.ts","sourceRoot":"","sources":["../../src/auth/erc8128.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,SAAS,EACd,KAAK,OAAO,EACb,MAAM,MAAM,CAAC;AAGd,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,KAAK,MAAM,EAAE,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,KAAK,MAAM,EAAE,CAAC;CACtB;AAyDD,yCAAyC;AACzC,wBAAsB,WAAW,CAC/B,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,EACrD,MAAM,EAAE,KAAK,MAAM,EAAE,EACrB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,aAAa,CAAC,CAWxB;AAED,oDAAoD;AACpD,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAgB7D;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,EACrD,MAAM,EAAE,KAAK,MAAM,EAAE,GACpB,OAAO,KAAK,CAwBd"}
@@ -0,0 +1,92 @@
1
+ import { AzethError } from '@azeth/common';
2
+ /** Generate a nonce for ERC-8128 authentication */
3
+ function generateNonce() {
4
+ const bytes = new Uint8Array(32); // H-8 fix: Increased from 16 to 32 bytes (256-bit entropy)
5
+ crypto.getRandomValues(bytes);
6
+ return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
7
+ }
8
+ /** Compute SHA-256 content digest for HTTP message signatures */
9
+ async function computeContentDigest(body) {
10
+ const encoder = new TextEncoder();
11
+ const data = encoder.encode(body);
12
+ const hashBuffer = await crypto.subtle.digest('SHA-256', data);
13
+ const hashArray = new Uint8Array(hashBuffer);
14
+ let binary = '';
15
+ for (const byte of hashArray) {
16
+ binary += String.fromCharCode(byte);
17
+ }
18
+ const hashBase64 = btoa(binary);
19
+ return `sha-256=:${hashBase64}:`;
20
+ }
21
+ /** Build the ERC-8128 signature base string
22
+ * Follows the HTTP Signature specification for machine-native auth
23
+ */
24
+ async function buildSignatureBase(method, url, body, nonce, created) {
25
+ const parsed = new URL(url);
26
+ const parts = [
27
+ `"@method": ${method.toUpperCase()}`,
28
+ `"@path": ${parsed.pathname}`,
29
+ `"@query": ${parsed.search || '?'}`,
30
+ `"@authority": ${parsed.host}`,
31
+ ];
32
+ if (nonce) {
33
+ parts.push(`"nonce": "${nonce}"`);
34
+ }
35
+ if (created !== undefined) {
36
+ parts.push(`"created": ${created}`);
37
+ }
38
+ if (body) {
39
+ const digest = await computeContentDigest(body);
40
+ parts.push(`"content-digest": ${digest}`);
41
+ }
42
+ return parts.join('\n');
43
+ }
44
+ /** Sign an HTTP request with ERC-8128 */
45
+ export async function signRequest(walletClient, signer, method, url, body) {
46
+ const nonce = generateNonce();
47
+ const created = Math.floor(Date.now() / 1000);
48
+ const signatureBase = await buildSignatureBase(method, url, body, nonce, created);
49
+ const signature = await walletClient.signMessage({
50
+ account: signer,
51
+ message: signatureBase,
52
+ });
53
+ return { signature, nonce, created, keyid: signer };
54
+ }
55
+ /** Build the ERC-8128 Authorization header value */
56
+ export function buildAuthHeader(signed) {
57
+ // CRITICAL-2 fix: Use cross-platform Uint8Array instead of Node.js Buffer
58
+ // so this works in browsers, Deno, Cloudflare Workers, and edge runtimes.
59
+ const hexStr = signed.signature.slice(2); // remove 0x prefix
60
+ // H-3 fix: Validate signature is exactly 65 bytes (130 hex chars)
61
+ if (hexStr.length !== 130) {
62
+ throw new AzethError('Invalid signature length — expected 65 bytes', 'INVALID_INPUT', { field: 'signature' });
63
+ }
64
+ const sigBytes = new Uint8Array(hexStr.match(/.{2}/g).map(b => parseInt(b, 16)));
65
+ // H-3 fix: Validate v value is canonical (27, 28, 0, or 1)
66
+ const v = sigBytes[64];
67
+ if (v !== 27 && v !== 28 && v !== 0 && v !== 1) {
68
+ throw new AzethError('Invalid signature recovery value', 'INVALID_INPUT', { field: 'signature' });
69
+ }
70
+ const sigBase64 = btoa(String.fromCharCode(...sigBytes));
71
+ return `ERC8128 sig=:${sigBase64}:; keyid="${signed.keyid}"; nonce="${signed.nonce}"; created=${signed.created}`;
72
+ }
73
+ /** Create a fetch wrapper that automatically adds ERC-8128 auth headers */
74
+ export function createSignedFetch(walletClient, signer) {
75
+ return async (input, init) => {
76
+ const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;
77
+ const method = init?.method ?? 'GET';
78
+ // MEDIUM-12 fix: Reject non-string body types that can't be included in the signature base.
79
+ // Without this, a ReadableStream/Blob/ArrayBuffer body would be silently excluded from the
80
+ // content digest, causing the server to verify a signature over a request without the body hash.
81
+ if (init?.body !== undefined && init.body !== null && typeof init.body !== 'string') {
82
+ throw new AzethError('ERC-8128 signed fetch requires a string body for content digest. Convert your body to a string first.', 'INVALID_INPUT', { field: 'body', bodyType: typeof init.body });
83
+ }
84
+ const body = typeof init?.body === 'string' ? init.body : undefined;
85
+ const signed = await signRequest(walletClient, signer, method, url, body);
86
+ const authHeader = buildAuthHeader(signed);
87
+ const headers = new Headers(init?.headers);
88
+ headers.set('Authorization', authHeader);
89
+ return fetch(input, { ...init, headers });
90
+ };
91
+ }
92
+ //# sourceMappingURL=erc8128.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"erc8128.js","sourceRoot":"","sources":["../../src/auth/erc8128.ts"],"names":[],"mappings":"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"}