@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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Azeth.ai
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# @azeth/sdk
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for the Azeth trust infrastructure. Provides `AzethKit` -- a single class for machine participants to interact with the Azeth protocol: smart accounts, x402 payments, reputation, messaging, and service discovery.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @azeth/sdk
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @azeth/sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Peer dependency: `viem`.
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { AzethKit } from '@azeth/sdk';
|
|
19
|
+
|
|
20
|
+
const kit = await AzethKit.create({
|
|
21
|
+
privateKey: process.env.AZETH_PRIVATE_KEY as `0x${string}`,
|
|
22
|
+
chain: 'baseSepolia',
|
|
23
|
+
bundlerUrl: `https://api.pimlico.io/v2/84532/rpc?apikey=${process.env.PIMLICO_API_KEY}`,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
// Check balances across all accounts with USD values
|
|
28
|
+
const balances = await kit.getAllBalances();
|
|
29
|
+
console.log('Total:', balances.grandTotalUSDFormatted);
|
|
30
|
+
|
|
31
|
+
// Transfer USDC
|
|
32
|
+
await kit.transfer({
|
|
33
|
+
to: '0xRecipient...' as `0x${string}`,
|
|
34
|
+
amount: 1_000_000n, // 1 USDC
|
|
35
|
+
token: '0xUSDC...' as `0x${string}`,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Pay for an x402 service
|
|
39
|
+
const { response } = await kit.fetch402('https://api.example.com/data');
|
|
40
|
+
const data = await response.json();
|
|
41
|
+
|
|
42
|
+
// Discover best service and pay in one call
|
|
43
|
+
const result = await kit.smartFetch402('price-feed');
|
|
44
|
+
console.log('Served by:', result.service.name);
|
|
45
|
+
} finally {
|
|
46
|
+
await kit.destroy();
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Key Features
|
|
51
|
+
|
|
52
|
+
- **Smart Accounts** -- Deploy ERC-4337 smart accounts with guardian guardrails (spending limits, whitelists, timelocks) via `createAccount()`
|
|
53
|
+
- **x402 Payments** -- Auto-detect and pay for HTTP 402 services with `fetch402()` and `smartFetch402()`
|
|
54
|
+
- **Reputation** -- Submit and query payment-weighted reputation via `submitOpinion()` and `getWeightedReputation()`
|
|
55
|
+
- **Service Discovery** -- Find services by capability and reputation via `discoverServices()`, with on-chain fallback
|
|
56
|
+
- **Payment Agreements** -- Create and manage recurring on-chain payments via `createPaymentAgreement()`
|
|
57
|
+
- **Messaging** -- Send and receive E2E encrypted messages via XMTP with `sendMessage()` and `onMessage()`
|
|
58
|
+
- **Auth** -- ERC-8128 machine-native HTTP signatures via `getSignedFetch()`
|
|
59
|
+
- **Budget Manager** -- Client-side reputation-aware spending tiers on top of on-chain guardian limits
|
|
60
|
+
- **Event System** -- Lifecycle hooks for payments, transfers, and deposits
|
|
61
|
+
|
|
62
|
+
## API Overview
|
|
63
|
+
|
|
64
|
+
### Account
|
|
65
|
+
|
|
66
|
+
| Method | Description |
|
|
67
|
+
|---|---|
|
|
68
|
+
| `AzethKit.create(config)` | Create an SDK instance |
|
|
69
|
+
| `kit.createAccount(params)` | Deploy smart account + registry entry |
|
|
70
|
+
| `kit.getBalance(account?)` | ETH/USDC/WETH balances |
|
|
71
|
+
| `kit.getAllBalances()` | All accounts with USD values |
|
|
72
|
+
| `kit.transfer(params)` | Send ETH or ERC-20 via UserOp |
|
|
73
|
+
| `kit.deposit(params)` | Fund smart account from EOA |
|
|
74
|
+
| `kit.getHistory(params?)` | Transaction history |
|
|
75
|
+
| `kit.setTokenWhitelist(token, allowed)` | Guardian token whitelist |
|
|
76
|
+
| `kit.setProtocolWhitelist(protocol, allowed)` | Guardian protocol whitelist |
|
|
77
|
+
|
|
78
|
+
### Payments
|
|
79
|
+
|
|
80
|
+
| Method | Description |
|
|
81
|
+
|---|---|
|
|
82
|
+
| `kit.fetch402(url, options?)` | Pay for x402 services |
|
|
83
|
+
| `kit.smartFetch402(capability, options?)` | Discover + pay + rate in one call |
|
|
84
|
+
| `kit.createPaymentAgreement(params)` | Recurring on-chain payments |
|
|
85
|
+
| `kit.executeAgreement(id)` | Execute a due agreement |
|
|
86
|
+
| `kit.cancelAgreement(id)` | Cancel an agreement |
|
|
87
|
+
| `kit.getAgreementData(id)` | Full agreement status |
|
|
88
|
+
|
|
89
|
+
### Registry and Reputation
|
|
90
|
+
|
|
91
|
+
| Method | Description |
|
|
92
|
+
|---|---|
|
|
93
|
+
| `kit.publishService(params)` | Register on trust registry |
|
|
94
|
+
| `kit.discoverServices(params)` | Search by capability/reputation |
|
|
95
|
+
| `kit.updateServiceMetadata(key, value)` | Update registry metadata |
|
|
96
|
+
| `kit.submitOpinion(opinion)` | Submit reputation opinion |
|
|
97
|
+
| `kit.getWeightedReputation(agentId)` | Payment-weighted reputation |
|
|
98
|
+
| `kit.getNetPaid(counterparty)` | Net payment delta |
|
|
99
|
+
|
|
100
|
+
### Messaging and Auth
|
|
101
|
+
|
|
102
|
+
| Method | Description |
|
|
103
|
+
|---|---|
|
|
104
|
+
| `kit.sendMessage(params)` | Send XMTP encrypted message |
|
|
105
|
+
| `kit.onMessage(handler)` | Listen for messages |
|
|
106
|
+
| `kit.canReach(address)` | Check XMTP reachability |
|
|
107
|
+
| `kit.getSignedFetch()` | ERC-8128 authenticated fetch |
|
|
108
|
+
|
|
109
|
+
### Lifecycle
|
|
110
|
+
|
|
111
|
+
| Method | Description |
|
|
112
|
+
|---|---|
|
|
113
|
+
| `kit.on(event, listener)` | Subscribe to events |
|
|
114
|
+
| `kit.destroy()` | Clean up and zero keys |
|
|
115
|
+
|
|
116
|
+
## Error Handling
|
|
117
|
+
|
|
118
|
+
All errors are `AzethError` with typed codes:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { AzethError } from '@azeth/common';
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
await kit.transfer({ to: '0x...', amount: 1_000_000n });
|
|
125
|
+
} catch (err) {
|
|
126
|
+
if (err instanceof AzethError) {
|
|
127
|
+
// err.code: 'INSUFFICIENT_BALANCE' | 'GUARDIAN_REJECTED' | 'BUDGET_EXCEEDED' | ...
|
|
128
|
+
console.error(err.code, err.message);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Full Documentation
|
|
134
|
+
|
|
135
|
+
See [docs/sdk.md](../../docs/sdk.md) for the comprehensive API reference with all method signatures, parameter types, return types, and detailed descriptions.
|
|
136
|
+
|
|
137
|
+
## License
|
|
138
|
+
|
|
139
|
+
MIT
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type PublicClient, type Chain, type Transport } from 'viem';
|
|
2
|
+
import { type SupportedChainName, type AggregatedBalanceResult } from '@azeth/common';
|
|
3
|
+
export interface BalanceResult {
|
|
4
|
+
/** Smart account ETH balance (primary identity) */
|
|
5
|
+
eth: bigint;
|
|
6
|
+
ethFormatted: string;
|
|
7
|
+
/** Smart account USDC balance */
|
|
8
|
+
usdc: bigint;
|
|
9
|
+
usdcFormatted: string;
|
|
10
|
+
/** Smart account tracked token balances */
|
|
11
|
+
tokens: Record<string, {
|
|
12
|
+
balance: bigint;
|
|
13
|
+
formatted: string;
|
|
14
|
+
}>;
|
|
15
|
+
/** EOA balances (for gas management) */
|
|
16
|
+
eoa: {
|
|
17
|
+
eth: bigint;
|
|
18
|
+
ethFormatted: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** Get ETH and token balances for a smart account and its owner EOA.
|
|
22
|
+
*
|
|
23
|
+
* Primary balances (eth, usdc, tokens) reflect the smart account.
|
|
24
|
+
* The eoa field shows the EOA's ETH balance for gas management.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getBalance(publicClient: PublicClient<Transport, Chain>, chainName: SupportedChainName, smartAccount: `0x${string}`, eoaAddress: `0x${string}`): Promise<BalanceResult>;
|
|
27
|
+
/** Get all balances for an owner's EOA + all smart accounts with USD values.
|
|
28
|
+
*
|
|
29
|
+
* **Primary path:** Single RPC call via AzethFactory.getOwnerBalancesAndUSD(owner)
|
|
30
|
+
* which queries AzethOracle for Chainlink-powered USD aggregation.
|
|
31
|
+
*
|
|
32
|
+
* **Fallback path:** If the aggregated oracle call reverts (e.g. due to a Chainlink
|
|
33
|
+
* feed issue or contract-level bug), falls back to individual balance queries.
|
|
34
|
+
* The fallback returns raw token balances WITHOUT USD values (usdValue = 0).
|
|
35
|
+
*
|
|
36
|
+
* Returns: EOA at index 0, smart accounts at index 1+.
|
|
37
|
+
* Each account has per-token balances with USD values and a total.
|
|
38
|
+
* Grand total USD sums across all accounts.
|
|
39
|
+
*/
|
|
40
|
+
export declare function getAllBalances(publicClient: PublicClient<Transport, Chain>, chainName: SupportedChainName, factoryAddress: `0x${string}`, owner: `0x${string}`): Promise<AggregatedBalanceResult>;
|
|
41
|
+
//# sourceMappingURL=balance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"balance.d.ts","sourceRoot":"","sources":["../../src/account/balance.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,SAAS,EAIf,MAAM,MAAM,CAAC;AACd,OAAO,EAKL,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAG7B,MAAM,eAAe,CAAC;AAIvB,MAAM,WAAW,aAAa;IAC5B,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/D,wCAAwC;IACxC,GAAG,EAAE;QACH,GAAG,EAAE,MAAM,CAAC;QACZ,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,EAC5C,SAAS,EAAE,kBAAkB,EAC7B,YAAY,EAAE,KAAK,MAAM,EAAE,EAC3B,UAAU,EAAE,KAAK,MAAM,EAAE,GACxB,OAAO,CAAC,aAAa,CAAC,CAkExB;AA4CD;;;;;;;;;;;;GAYG;AACH,wBAAsB,cAAc,CAClC,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,EAC5C,SAAS,EAAE,kBAAkB,EAC7B,cAAc,EAAE,KAAK,MAAM,EAAE,EAC7B,KAAK,EAAE,KAAK,MAAM,EAAE,GACnB,OAAO,CAAC,uBAAuB,CAAC,CA2ClC"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { erc20Abi, formatEther, formatUnits, } from 'viem';
|
|
2
|
+
import { AzethError, TOKENS, formatTokenAmount, formatAddress, } from '@azeth/common';
|
|
3
|
+
import { AzethFactoryAbi } from '@azeth/common/abis';
|
|
4
|
+
import { withRetry } from '../utils/retry.js';
|
|
5
|
+
/** Get ETH and token balances for a smart account and its owner EOA.
|
|
6
|
+
*
|
|
7
|
+
* Primary balances (eth, usdc, tokens) reflect the smart account.
|
|
8
|
+
* The eoa field shows the EOA's ETH balance for gas management.
|
|
9
|
+
*/
|
|
10
|
+
export async function getBalance(publicClient, chainName, smartAccount, eoaAddress) {
|
|
11
|
+
// Fetch smart account ETH balance
|
|
12
|
+
let ethBalance;
|
|
13
|
+
try {
|
|
14
|
+
ethBalance = await withRetry(() => publicClient.getBalance({ address: smartAccount }));
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
if (err instanceof AzethError)
|
|
18
|
+
throw err;
|
|
19
|
+
throw new AzethError(err instanceof Error ? err.message : 'Failed to fetch ETH balance', 'NETWORK_ERROR', { originalError: err instanceof Error ? err.name : undefined });
|
|
20
|
+
}
|
|
21
|
+
// Fetch EOA ETH balance (for gas management)
|
|
22
|
+
let eoaEthBalance;
|
|
23
|
+
try {
|
|
24
|
+
eoaEthBalance = await withRetry(() => publicClient.getBalance({ address: eoaAddress }));
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
eoaEthBalance = 0n; // Non-fatal — smart account balance is primary
|
|
28
|
+
}
|
|
29
|
+
const tokens = {};
|
|
30
|
+
let usdcBalance = 0n;
|
|
31
|
+
const chainTokens = TOKENS[chainName];
|
|
32
|
+
if (chainTokens.USDC && chainTokens.USDC !== '0x') {
|
|
33
|
+
try {
|
|
34
|
+
usdcBalance = await withRetry(() => publicClient.readContract({
|
|
35
|
+
address: chainTokens.USDC,
|
|
36
|
+
abi: erc20Abi,
|
|
37
|
+
functionName: 'balanceOf',
|
|
38
|
+
args: [smartAccount],
|
|
39
|
+
}));
|
|
40
|
+
tokens['USDC'] = { balance: usdcBalance, formatted: formatUnits(usdcBalance, 6) };
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// Token contract may not exist on this chain
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (chainTokens.WETH && chainTokens.WETH !== '0x') {
|
|
47
|
+
try {
|
|
48
|
+
const wethBalance = await withRetry(() => publicClient.readContract({
|
|
49
|
+
address: chainTokens.WETH,
|
|
50
|
+
abi: erc20Abi,
|
|
51
|
+
functionName: 'balanceOf',
|
|
52
|
+
args: [smartAccount],
|
|
53
|
+
}));
|
|
54
|
+
tokens['WETH'] = { balance: wethBalance, formatted: formatEther(wethBalance) };
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Token contract may not exist
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
eth: ethBalance,
|
|
62
|
+
ethFormatted: formatEther(ethBalance),
|
|
63
|
+
usdc: usdcBalance,
|
|
64
|
+
usdcFormatted: formatUnits(usdcBalance, 6),
|
|
65
|
+
tokens,
|
|
66
|
+
eoa: {
|
|
67
|
+
eth: eoaEthBalance,
|
|
68
|
+
ethFormatted: formatEther(eoaEthBalance),
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const NATIVE_ETH = '0x0000000000000000000000000000000000000000';
|
|
73
|
+
/** Build a token address → metadata map for the given chain */
|
|
74
|
+
function buildTokenMeta(chainName) {
|
|
75
|
+
const meta = {
|
|
76
|
+
[NATIVE_ETH]: { symbol: 'ETH', decimals: 18 },
|
|
77
|
+
};
|
|
78
|
+
const chainTokens = TOKENS[chainName];
|
|
79
|
+
if (chainTokens.USDC) {
|
|
80
|
+
meta[chainTokens.USDC.toLowerCase()] = { symbol: 'USDC', decimals: 6 };
|
|
81
|
+
}
|
|
82
|
+
if (chainTokens.WETH) {
|
|
83
|
+
meta[chainTokens.WETH.toLowerCase()] = { symbol: 'WETH', decimals: 18 };
|
|
84
|
+
}
|
|
85
|
+
return meta;
|
|
86
|
+
}
|
|
87
|
+
/** Format a bigint 18-decimal USD value to a human-readable string */
|
|
88
|
+
function formatUSD(value18) {
|
|
89
|
+
return `$${formatTokenAmount(value18, 18, 2)}`;
|
|
90
|
+
}
|
|
91
|
+
/** Map a raw on-chain TokenBalance to a client-friendly TokenBalanceUSD */
|
|
92
|
+
function mapTokenBalance(tb, meta) {
|
|
93
|
+
const tokenAddr = tb.token.toLowerCase();
|
|
94
|
+
const info = meta[tokenAddr] ?? { symbol: formatAddress(tb.token), decimals: 18 };
|
|
95
|
+
return {
|
|
96
|
+
token: tb.token,
|
|
97
|
+
symbol: info.symbol,
|
|
98
|
+
balance: tb.balance,
|
|
99
|
+
balanceFormatted: formatTokenAmount(tb.balance, info.decimals),
|
|
100
|
+
usdValue: tb.usdValue,
|
|
101
|
+
usdFormatted: formatUSD(tb.usdValue),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/** Get all balances for an owner's EOA + all smart accounts with USD values.
|
|
105
|
+
*
|
|
106
|
+
* **Primary path:** Single RPC call via AzethFactory.getOwnerBalancesAndUSD(owner)
|
|
107
|
+
* which queries AzethOracle for Chainlink-powered USD aggregation.
|
|
108
|
+
*
|
|
109
|
+
* **Fallback path:** If the aggregated oracle call reverts (e.g. due to a Chainlink
|
|
110
|
+
* feed issue or contract-level bug), falls back to individual balance queries.
|
|
111
|
+
* The fallback returns raw token balances WITHOUT USD values (usdValue = 0).
|
|
112
|
+
*
|
|
113
|
+
* Returns: EOA at index 0, smart accounts at index 1+.
|
|
114
|
+
* Each account has per-token balances with USD values and a total.
|
|
115
|
+
* Grand total USD sums across all accounts.
|
|
116
|
+
*/
|
|
117
|
+
export async function getAllBalances(publicClient, chainName, factoryAddress, owner) {
|
|
118
|
+
// Primary path: aggregated oracle query (single RPC call)
|
|
119
|
+
try {
|
|
120
|
+
const result = await withRetry(() => publicClient.readContract({
|
|
121
|
+
address: factoryAddress,
|
|
122
|
+
abi: AzethFactoryAbi,
|
|
123
|
+
functionName: 'getOwnerBalancesAndUSD',
|
|
124
|
+
args: [owner],
|
|
125
|
+
}));
|
|
126
|
+
const rawBalances = result[0];
|
|
127
|
+
const grandTotalUSD = result[1];
|
|
128
|
+
const meta = buildTokenMeta(chainName);
|
|
129
|
+
const accounts = rawBalances.map((ab, i) => {
|
|
130
|
+
// Deduplicate token entries: the on-chain oracle allocates balances[tokens.length+1]
|
|
131
|
+
// and skips address(0) in the ERC-20 loop (already handled as native ETH at index 0).
|
|
132
|
+
// This leaves a phantom zeroed entry {token: 0x0, balance: 0, usdValue: 0}.
|
|
133
|
+
// Filter it out by tracking seen token addresses and dropping zero-balance duplicates.
|
|
134
|
+
const seen = new Set();
|
|
135
|
+
const deduped = ab.balances.filter((tb) => {
|
|
136
|
+
const key = tb.token.toLowerCase();
|
|
137
|
+
if (seen.has(key) && tb.balance === 0n && tb.usdValue === 0n)
|
|
138
|
+
return false;
|
|
139
|
+
seen.add(key);
|
|
140
|
+
return true;
|
|
141
|
+
});
|
|
142
|
+
return {
|
|
143
|
+
account: ab.account,
|
|
144
|
+
label: i === 0 ? 'EOA' : `Smart Account #${i}`,
|
|
145
|
+
balances: deduped.map((tb) => mapTokenBalance(tb, meta)),
|
|
146
|
+
totalUSD: ab.totalUSD,
|
|
147
|
+
totalUSDFormatted: formatUSD(ab.totalUSD),
|
|
148
|
+
};
|
|
149
|
+
});
|
|
150
|
+
return { accounts, grandTotalUSD, grandTotalUSDFormatted: formatUSD(grandTotalUSD) };
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// Fallback: individual balance queries without USD aggregation.
|
|
154
|
+
// Known trigger: the on-chain oracle reverts when _supportedTokens includes
|
|
155
|
+
// address(0) because Solidity try/catch cannot catch balanceOf() calls to
|
|
156
|
+
// non-contract addresses (the call succeeds but returns empty data, failing
|
|
157
|
+
// ABI decode). This is a contract-level issue — the fallback provides resilience.
|
|
158
|
+
return _fallbackGetAllBalances(publicClient, chainName, factoryAddress, owner);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/** Fallback balance fetcher: queries individual ETH + ERC-20 balances per account.
|
|
162
|
+
*
|
|
163
|
+
* Called when the aggregated AzethOracle.getBalancesAndUSD() reverts on-chain.
|
|
164
|
+
* Returns balances with zero USD values since the oracle is unavailable.
|
|
165
|
+
*
|
|
166
|
+
* @internal
|
|
167
|
+
*/
|
|
168
|
+
async function _fallbackGetAllBalances(publicClient, chainName, factoryAddress, owner) {
|
|
169
|
+
// 1. Get smart accounts from factory
|
|
170
|
+
let smartAccounts = [];
|
|
171
|
+
try {
|
|
172
|
+
smartAccounts = await withRetry(() => publicClient.readContract({
|
|
173
|
+
address: factoryAddress,
|
|
174
|
+
abi: AzethFactoryAbi,
|
|
175
|
+
functionName: 'getAccountsByOwner',
|
|
176
|
+
args: [owner],
|
|
177
|
+
}));
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
// If even getAccountsByOwner fails, return just the EOA
|
|
181
|
+
}
|
|
182
|
+
const allAccounts = [owner, ...smartAccounts];
|
|
183
|
+
const chainTokens = TOKENS[chainName];
|
|
184
|
+
const accounts = [];
|
|
185
|
+
for (let i = 0; i < allAccounts.length; i++) {
|
|
186
|
+
const account = allAccounts[i];
|
|
187
|
+
const balances = [];
|
|
188
|
+
// Native ETH balance
|
|
189
|
+
let ethBalance = 0n;
|
|
190
|
+
try {
|
|
191
|
+
ethBalance = await publicClient.getBalance({ address: account });
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
// Non-fatal: RPC failure for this account
|
|
195
|
+
}
|
|
196
|
+
balances.push({
|
|
197
|
+
token: '0x0000000000000000000000000000000000000000',
|
|
198
|
+
symbol: 'ETH',
|
|
199
|
+
balance: ethBalance,
|
|
200
|
+
balanceFormatted: formatTokenAmount(ethBalance, 18),
|
|
201
|
+
usdValue: 0n,
|
|
202
|
+
usdFormatted: '$0.00 (oracle unavailable)',
|
|
203
|
+
});
|
|
204
|
+
// USDC balance
|
|
205
|
+
if (chainTokens.USDC && chainTokens.USDC !== '0x') {
|
|
206
|
+
let usdcBalance = 0n;
|
|
207
|
+
try {
|
|
208
|
+
usdcBalance = await publicClient.readContract({
|
|
209
|
+
address: chainTokens.USDC,
|
|
210
|
+
abi: erc20Abi,
|
|
211
|
+
functionName: 'balanceOf',
|
|
212
|
+
args: [account],
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
// Non-fatal: token contract may not exist
|
|
217
|
+
}
|
|
218
|
+
balances.push({
|
|
219
|
+
token: chainTokens.USDC,
|
|
220
|
+
symbol: 'USDC',
|
|
221
|
+
balance: usdcBalance,
|
|
222
|
+
balanceFormatted: formatTokenAmount(usdcBalance, 6),
|
|
223
|
+
usdValue: 0n,
|
|
224
|
+
usdFormatted: '$0.00 (oracle unavailable)',
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
// WETH balance
|
|
228
|
+
if (chainTokens.WETH && chainTokens.WETH !== '0x') {
|
|
229
|
+
let wethBalance = 0n;
|
|
230
|
+
try {
|
|
231
|
+
wethBalance = await publicClient.readContract({
|
|
232
|
+
address: chainTokens.WETH,
|
|
233
|
+
abi: erc20Abi,
|
|
234
|
+
functionName: 'balanceOf',
|
|
235
|
+
args: [account],
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
// Non-fatal: token contract may not exist
|
|
240
|
+
}
|
|
241
|
+
balances.push({
|
|
242
|
+
token: chainTokens.WETH,
|
|
243
|
+
symbol: 'WETH',
|
|
244
|
+
balance: wethBalance,
|
|
245
|
+
balanceFormatted: formatTokenAmount(wethBalance, 18),
|
|
246
|
+
usdValue: 0n,
|
|
247
|
+
usdFormatted: '$0.00 (oracle unavailable)',
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
accounts.push({
|
|
251
|
+
account,
|
|
252
|
+
label: i === 0 ? 'EOA' : `Smart Account #${i}`,
|
|
253
|
+
balances,
|
|
254
|
+
totalUSD: 0n,
|
|
255
|
+
totalUSDFormatted: '$0.00 (oracle unavailable)',
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
accounts,
|
|
260
|
+
grandTotalUSD: 0n,
|
|
261
|
+
grandTotalUSDFormatted: '$0.00 (oracle unavailable)',
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=balance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"balance.js","sourceRoot":"","sources":["../../src/account/balance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type PublicClient, type WalletClient, type Chain, type Transport, type Account } from 'viem';
|
|
2
|
+
import { type Guardrails, type AzethContractAddresses } from '@azeth/common';
|
|
3
|
+
import { type RegisterParams } from '../registry/register.js';
|
|
4
|
+
export interface CreateAccountParams {
|
|
5
|
+
owner: `0x${string}`;
|
|
6
|
+
salt?: `0x${string}`;
|
|
7
|
+
guardrails: Guardrails;
|
|
8
|
+
protocols?: `0x${string}`[];
|
|
9
|
+
tokens?: `0x${string}`[];
|
|
10
|
+
/** Registry metadata for ERC-8004 trust registry registration.
|
|
11
|
+
* Pass undefined to skip registration (tokenId will be 0). */
|
|
12
|
+
registry?: RegisterParams;
|
|
13
|
+
}
|
|
14
|
+
export interface CreateAccountResult {
|
|
15
|
+
account: `0x${string}`;
|
|
16
|
+
tokenId: bigint;
|
|
17
|
+
txHash: `0x${string}`;
|
|
18
|
+
}
|
|
19
|
+
/** Deploy a new Azeth smart account via the AzethFactory v11 (one-call setup).
|
|
20
|
+
*
|
|
21
|
+
* Single atomic transaction: deploys ERC-1967 proxy, installs all 4 modules,
|
|
22
|
+
* registers on ERC-8004 trust registry (optional), and permanently revokes factory access.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createAccount(publicClient: PublicClient<Transport, Chain>, walletClient: WalletClient<Transport, Chain, Account>, addresses: AzethContractAddresses, params: CreateAccountParams): Promise<CreateAccountResult>;
|
|
25
|
+
/** Compute the deterministic address for an account without deploying */
|
|
26
|
+
export declare function getAccountAddress(publicClient: PublicClient<Transport, Chain>, addresses: AzethContractAddresses, owner: `0x${string}`, salt: `0x${string}`): Promise<`0x${string}`>;
|
|
27
|
+
//# sourceMappingURL=create.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/account/create.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,EAAsB,KAAK,UAAU,EAAE,KAAK,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAIjG,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAe7E,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,KAAK,MAAM,EAAE,CAAC;IACrB,IAAI,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,CAAC,EAAE,KAAK,MAAM,EAAE,EAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,KAAK,MAAM,EAAE,EAAE,CAAC;IACzB;mEAC+D;IAC/D,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,EAC5C,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,EACrD,SAAS,EAAE,sBAAsB,EACjC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAgF9B;AAED,yEAAyE;AACzE,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,EAC5C,SAAS,EAAE,sBAAsB,EACjC,KAAK,EAAE,KAAK,MAAM,EAAE,EACpB,IAAI,EAAE,KAAK,MAAM,EAAE,GAClB,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAaxB"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { keccak256, toBytes, pad, toHex, } from 'viem';
|
|
2
|
+
import { AzethFactoryAbi } from '@azeth/common/abis';
|
|
3
|
+
import { AzethError, TOKENS } from '@azeth/common';
|
|
4
|
+
import { requireAddress } from '../utils/addresses.js';
|
|
5
|
+
import { withRetry } from '../utils/retry.js';
|
|
6
|
+
import { wrapContractError } from '../utils/errors.js';
|
|
7
|
+
import { buildAgentURI } from '../registry/register.js';
|
|
8
|
+
const ETH_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
9
|
+
/** Derive default token whitelist from chain ID.
|
|
10
|
+
* Includes native ETH (address(0)), USDC, and WETH so that payment agreements
|
|
11
|
+
* and other executor-module operations work without manual whitelisting. */
|
|
12
|
+
function getDefaultTokenWhitelist(chainId) {
|
|
13
|
+
if (chainId === 84532)
|
|
14
|
+
return [ETH_ADDRESS, TOKENS.baseSepolia.USDC, TOKENS.baseSepolia.WETH];
|
|
15
|
+
if (chainId === 8453)
|
|
16
|
+
return [ETH_ADDRESS, TOKENS.base.USDC, TOKENS.base.WETH];
|
|
17
|
+
if (chainId === 11155111)
|
|
18
|
+
return [ETH_ADDRESS, TOKENS.ethereumSepolia.USDC, TOKENS.ethereumSepolia.WETH];
|
|
19
|
+
if (chainId === 1)
|
|
20
|
+
return [ETH_ADDRESS, TOKENS.ethereum.USDC, TOKENS.ethereum.WETH];
|
|
21
|
+
return [ETH_ADDRESS]; // fallback: at least whitelist native ETH
|
|
22
|
+
}
|
|
23
|
+
/** Deploy a new Azeth smart account via the AzethFactory v11 (one-call setup).
|
|
24
|
+
*
|
|
25
|
+
* Single atomic transaction: deploys ERC-1967 proxy, installs all 4 modules,
|
|
26
|
+
* registers on ERC-8004 trust registry (optional), and permanently revokes factory access.
|
|
27
|
+
*/
|
|
28
|
+
export async function createAccount(publicClient, walletClient, addresses, params) {
|
|
29
|
+
const factoryAddress = requireAddress(addresses, 'factory');
|
|
30
|
+
// Auto-increment salt based on existing account count when no explicit salt is provided.
|
|
31
|
+
// This allows one EOA to create up to MAX_ACCOUNTS_PER_OWNER (100) smart accounts.
|
|
32
|
+
// Salt 0 = first account (backwards-compatible), 1 = second, etc.
|
|
33
|
+
let salt;
|
|
34
|
+
if (params.salt) {
|
|
35
|
+
salt = params.salt;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const existing = await withRetry(() => publicClient.readContract({
|
|
39
|
+
address: factoryAddress,
|
|
40
|
+
abi: AzethFactoryAbi,
|
|
41
|
+
functionName: 'getAccountsByOwner',
|
|
42
|
+
args: [params.owner],
|
|
43
|
+
}));
|
|
44
|
+
salt = pad(toHex(existing.length), { size: 32 });
|
|
45
|
+
}
|
|
46
|
+
const agentURI = params.registry ? buildAgentURI(params.registry) : '';
|
|
47
|
+
let txHash;
|
|
48
|
+
try {
|
|
49
|
+
txHash = await walletClient.writeContract({
|
|
50
|
+
address: factoryAddress,
|
|
51
|
+
abi: AzethFactoryAbi,
|
|
52
|
+
functionName: 'createAccount',
|
|
53
|
+
args: [
|
|
54
|
+
params.owner,
|
|
55
|
+
salt,
|
|
56
|
+
params.guardrails,
|
|
57
|
+
params.protocols ?? [],
|
|
58
|
+
params.tokens ?? getDefaultTokenWhitelist(publicClient.chain?.id),
|
|
59
|
+
agentURI,
|
|
60
|
+
],
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
throw wrapContractError(err, 'NETWORK_ERROR');
|
|
65
|
+
}
|
|
66
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash, timeout: 120_000 });
|
|
67
|
+
if (receipt.status === 'reverted') {
|
|
68
|
+
throw new AzethError('Transaction reverted', 'NETWORK_ERROR', { txHash });
|
|
69
|
+
}
|
|
70
|
+
// Parse AccountCreated event from receipt
|
|
71
|
+
// Event: AccountCreated(address indexed account, address indexed owner, bytes32 salt, uint256 tokenId)
|
|
72
|
+
const ACCOUNT_CREATED_TOPIC = keccak256(toBytes('AccountCreated(address,address,bytes32,uint256)'));
|
|
73
|
+
let account = '0x0000000000000000000000000000000000000000';
|
|
74
|
+
let tokenId = 0n;
|
|
75
|
+
for (const log of receipt.logs) {
|
|
76
|
+
if (log.address.toLowerCase() === factoryAddress.toLowerCase()
|
|
77
|
+
&& log.topics[0] === ACCOUNT_CREATED_TOPIC
|
|
78
|
+
&& log.topics.length >= 3) {
|
|
79
|
+
// account is the first indexed topic (padded to 32 bytes)
|
|
80
|
+
account = ('0x' + (log.topics[1] ?? '').slice(26));
|
|
81
|
+
// tokenId is in the data field (non-indexed)
|
|
82
|
+
if (log.data && log.data.length >= 130) {
|
|
83
|
+
// data contains: salt (bytes32) + tokenId (uint256)
|
|
84
|
+
// tokenId is at offset 32 bytes (64 hex chars) after 0x prefix
|
|
85
|
+
tokenId = BigInt('0x' + log.data.slice(66, 130));
|
|
86
|
+
}
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (account === '0x0000000000000000000000000000000000000000') {
|
|
91
|
+
// Fallback: compute deterministically
|
|
92
|
+
account = await withRetry(() => publicClient.readContract({
|
|
93
|
+
address: factoryAddress,
|
|
94
|
+
abi: AzethFactoryAbi,
|
|
95
|
+
functionName: 'getAddress',
|
|
96
|
+
args: [params.owner, salt],
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
return { account, tokenId, txHash };
|
|
100
|
+
}
|
|
101
|
+
/** Compute the deterministic address for an account without deploying */
|
|
102
|
+
export async function getAccountAddress(publicClient, addresses, owner, salt) {
|
|
103
|
+
const factoryAddress = requireAddress(addresses, 'factory');
|
|
104
|
+
try {
|
|
105
|
+
return await withRetry(() => publicClient.readContract({
|
|
106
|
+
address: factoryAddress,
|
|
107
|
+
abi: AzethFactoryAbi,
|
|
108
|
+
functionName: 'getAddress',
|
|
109
|
+
args: [owner, salt],
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
throw wrapContractError(err, 'NETWORK_ERROR');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/account/create.ts"],"names":[],"mappings":"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"}
|