@awarizon/web3 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,176 @@
1
+ import { Chain, WalletClient, Address, Abi, PublicClient } from 'viem';
2
+ export { Abi, Address, Chain, Hash, TransactionReceipt, WalletClient } from 'viem';
3
+ import { WalletEngine } from '@awarizon/wallet-engine';
4
+ export { ChainSwitchError, InvalidMnemonicError, InvalidPrivateKeyError, WalletEngine, WalletNotConnectedError } from '@awarizon/wallet-engine';
5
+ export { ContractExecutionError, GasEstimationError, SimulationError, TransactionEngine, TransactionResult, TransactionTimeoutError } from '@awarizon/tx-engine';
6
+ export { DuplicateFunctionError, InvalidABIError, UnsupportedABIItemError, generateAllMethodSignatures, generateMethodSignature, isPayableFunction, isWriteFunction, parseABI } from '@awarizon/abi-engine';
7
+
8
+ interface AwarizonConfig {
9
+ /**
10
+ * Target chain. Accepts:
11
+ * - a string identifier: "base", "mainnet", "polygon", etc.
12
+ * - a viem Chain object: `import { base } from "viem/chains"`
13
+ */
14
+ chain: Chain | string;
15
+ /**
16
+ * Optional RPC URL override.
17
+ * If omitted, the chain's default public RPC endpoint is used.
18
+ */
19
+ rpcUrl?: string;
20
+ /**
21
+ * Optional pre-connected external signer.
22
+ * Equivalent to calling `sdk.connectWallet(signer)` after construction.
23
+ */
24
+ signer?: WalletClient;
25
+ }
26
+ interface ContractConfig<TAbi extends Abi = Abi> {
27
+ /** The deployed contract address */
28
+ address: Address;
29
+ /** The contract ABI */
30
+ abi: TAbi;
31
+ }
32
+ /** Callback type returned by contract.on() for cleaning up event subscriptions */
33
+ type EventUnsubscribe = () => void;
34
+ /** Options accepted by payable write methods */
35
+ interface PayableOptions {
36
+ /** ETH value in wei */
37
+ value?: bigint;
38
+ /** Optional gas limit override */
39
+ gas?: bigint;
40
+ }
41
+ /**
42
+ * The dynamically-generated contract instance returned by sdk.contract().
43
+ *
44
+ * Every function in the ABI is exposed as a method:
45
+ * - read functions (view/pure) → return decoded values
46
+ * - write functions (nonpayable/payable) → return { hash, receipt }
47
+ *
48
+ * Additional built-in methods:
49
+ * - on(event, callback) → subscribe to events; returns unsubscribe fn
50
+ * - estimateGas(method, ...args) → estimate gas for a write call
51
+ */
52
+ interface ContractInstance {
53
+ [method: string]: ((...args: unknown[]) => Promise<unknown>) | unknown;
54
+ /** Subscribe to a contract event. Returns an unsubscribe function. */
55
+ on(event: string, callback: (log: unknown) => void): EventUnsubscribe;
56
+ /** Estimate gas for a write function before sending */
57
+ estimateGas(method: string, ...args: unknown[]): Promise<bigint>;
58
+ /** The contract address this instance is bound to */
59
+ readonly _address: Address;
60
+ /** The ABI used to generate this instance */
61
+ readonly _abi: Abi;
62
+ }
63
+ interface SDKWalletInfo {
64
+ address: Address;
65
+ chain: Chain;
66
+ isExternal: boolean;
67
+ }
68
+
69
+ declare class NetworkMismatchError extends Error {
70
+ readonly code: "NETWORK_MISMATCH";
71
+ readonly expected: string;
72
+ readonly got: string;
73
+ constructor(expected: string | number, got: string | number);
74
+ }
75
+ declare class ProviderError extends Error {
76
+ readonly code: "PROVIDER_ERROR";
77
+ constructor(message: string);
78
+ }
79
+ declare class ContractNotLoadedError extends Error {
80
+ readonly code: "CONTRACT_NOT_LOADED";
81
+ constructor(address: string);
82
+ }
83
+ declare class UnsupportedChainError extends Error {
84
+ readonly code: "UNSUPPORTED_CHAIN";
85
+ readonly chain: string;
86
+ constructor(chain: string);
87
+ }
88
+
89
+ /**
90
+ * The primary entry point for the Awarizon Web3 SDK.
91
+ *
92
+ * ```ts
93
+ * const sdk = new AwarizonWeb3({ chain: "base" })
94
+ *
95
+ * // Internal wallet
96
+ * const wallet = await sdk.wallet.create()
97
+ *
98
+ * // Load a contract and call it
99
+ * const staking = await sdk.contract({ address: "0x...", abi })
100
+ * await staking.stake(100n)
101
+ * const balance = await staking.getBalance(wallet.address)
102
+ *
103
+ * // Listen for events
104
+ * staking.on("Staked", (log) => console.log(log))
105
+ * ```
106
+ */
107
+ declare class AwarizonWeb3 {
108
+ /** The resolved viem Chain */
109
+ readonly chain: Chain;
110
+ /** Internal wallet + signer management */
111
+ readonly wallet: WalletEngine;
112
+ /** The underlying viem PublicClient used for reads */
113
+ readonly publicClient: PublicClient;
114
+ constructor(config: AwarizonConfig);
115
+ /**
116
+ * Connect an external wallet client (wagmi, WalletConnect, viem, EIP-1193).
117
+ * The connected signer takes priority over any internal wallet.
118
+ *
119
+ * @example
120
+ * sdk.connectWallet(walletClient)
121
+ */
122
+ connectWallet(walletClient: WalletClient): this;
123
+ /**
124
+ * Disconnect the externally-connected wallet.
125
+ * Falls back to the internal wallet if one is loaded.
126
+ */
127
+ disconnectWallet(): this;
128
+ /**
129
+ * Switch the active chain.
130
+ * Rebuilds the PublicClient and internal WalletClient for the new chain.
131
+ */
132
+ switchChain(chain: Chain | string): Promise<this>;
133
+ /**
134
+ * Returns a summary of the currently active wallet.
135
+ * @throws {WalletNotConnectedError} if no wallet is connected
136
+ */
137
+ getWalletInfo(): SDKWalletInfo;
138
+ /**
139
+ * Load a deployed smart contract and return a fully typed, ABI-powered
140
+ * instance. Every function in the ABI is exposed as a direct method.
141
+ *
142
+ * **Read functions** (view / pure) use the PublicClient — no signer needed.
143
+ * **Write functions** (nonpayable / payable) use the active WalletClient.
144
+ *
145
+ * @example
146
+ * const token = await sdk.contract({ address: "0x...", abi: ERC20_ABI })
147
+ * const balance = await token.balanceOf(address) // read
148
+ * await token.transfer(to, 100n) // write
149
+ * token.on("Transfer", handler) // events
150
+ */
151
+ contract<TAbi extends Abi>(config: ContractConfig<TAbi>): Promise<ContractInstance>;
152
+ /**
153
+ * Returns the chain ID of the current chain.
154
+ * Useful for runtime network validation.
155
+ */
156
+ get chainId(): number;
157
+ /**
158
+ * Check whether any wallet (internal or external) is connected.
159
+ */
160
+ get isConnected(): boolean;
161
+ }
162
+
163
+ declare const CHAINS: Record<string, Chain>;
164
+ /**
165
+ * Resolves a chain string identifier or a viem Chain object to a Chain.
166
+ *
167
+ * @example
168
+ * resolveChain("base") // → Chain object for Base
169
+ * resolveChain(base) // → same Chain object, passthrough
170
+ * resolveChain("unknown") // → throws Error
171
+ */
172
+ declare function resolveChain(chain: Chain | string): Chain;
173
+ /** Returns a list of all unique supported chain IDs */
174
+ declare function getSupportedChainIds(): number[];
175
+
176
+ export { type AwarizonConfig, AwarizonWeb3, CHAINS, type ContractConfig, type ContractInstance, ContractNotLoadedError, type EventUnsubscribe, NetworkMismatchError, type PayableOptions, ProviderError, type SDKWalletInfo, UnsupportedChainError, getSupportedChainIds, resolveChain };
@@ -0,0 +1,176 @@
1
+ import { Chain, WalletClient, Address, Abi, PublicClient } from 'viem';
2
+ export { Abi, Address, Chain, Hash, TransactionReceipt, WalletClient } from 'viem';
3
+ import { WalletEngine } from '@awarizon/wallet-engine';
4
+ export { ChainSwitchError, InvalidMnemonicError, InvalidPrivateKeyError, WalletEngine, WalletNotConnectedError } from '@awarizon/wallet-engine';
5
+ export { ContractExecutionError, GasEstimationError, SimulationError, TransactionEngine, TransactionResult, TransactionTimeoutError } from '@awarizon/tx-engine';
6
+ export { DuplicateFunctionError, InvalidABIError, UnsupportedABIItemError, generateAllMethodSignatures, generateMethodSignature, isPayableFunction, isWriteFunction, parseABI } from '@awarizon/abi-engine';
7
+
8
+ interface AwarizonConfig {
9
+ /**
10
+ * Target chain. Accepts:
11
+ * - a string identifier: "base", "mainnet", "polygon", etc.
12
+ * - a viem Chain object: `import { base } from "viem/chains"`
13
+ */
14
+ chain: Chain | string;
15
+ /**
16
+ * Optional RPC URL override.
17
+ * If omitted, the chain's default public RPC endpoint is used.
18
+ */
19
+ rpcUrl?: string;
20
+ /**
21
+ * Optional pre-connected external signer.
22
+ * Equivalent to calling `sdk.connectWallet(signer)` after construction.
23
+ */
24
+ signer?: WalletClient;
25
+ }
26
+ interface ContractConfig<TAbi extends Abi = Abi> {
27
+ /** The deployed contract address */
28
+ address: Address;
29
+ /** The contract ABI */
30
+ abi: TAbi;
31
+ }
32
+ /** Callback type returned by contract.on() for cleaning up event subscriptions */
33
+ type EventUnsubscribe = () => void;
34
+ /** Options accepted by payable write methods */
35
+ interface PayableOptions {
36
+ /** ETH value in wei */
37
+ value?: bigint;
38
+ /** Optional gas limit override */
39
+ gas?: bigint;
40
+ }
41
+ /**
42
+ * The dynamically-generated contract instance returned by sdk.contract().
43
+ *
44
+ * Every function in the ABI is exposed as a method:
45
+ * - read functions (view/pure) → return decoded values
46
+ * - write functions (nonpayable/payable) → return { hash, receipt }
47
+ *
48
+ * Additional built-in methods:
49
+ * - on(event, callback) → subscribe to events; returns unsubscribe fn
50
+ * - estimateGas(method, ...args) → estimate gas for a write call
51
+ */
52
+ interface ContractInstance {
53
+ [method: string]: ((...args: unknown[]) => Promise<unknown>) | unknown;
54
+ /** Subscribe to a contract event. Returns an unsubscribe function. */
55
+ on(event: string, callback: (log: unknown) => void): EventUnsubscribe;
56
+ /** Estimate gas for a write function before sending */
57
+ estimateGas(method: string, ...args: unknown[]): Promise<bigint>;
58
+ /** The contract address this instance is bound to */
59
+ readonly _address: Address;
60
+ /** The ABI used to generate this instance */
61
+ readonly _abi: Abi;
62
+ }
63
+ interface SDKWalletInfo {
64
+ address: Address;
65
+ chain: Chain;
66
+ isExternal: boolean;
67
+ }
68
+
69
+ declare class NetworkMismatchError extends Error {
70
+ readonly code: "NETWORK_MISMATCH";
71
+ readonly expected: string;
72
+ readonly got: string;
73
+ constructor(expected: string | number, got: string | number);
74
+ }
75
+ declare class ProviderError extends Error {
76
+ readonly code: "PROVIDER_ERROR";
77
+ constructor(message: string);
78
+ }
79
+ declare class ContractNotLoadedError extends Error {
80
+ readonly code: "CONTRACT_NOT_LOADED";
81
+ constructor(address: string);
82
+ }
83
+ declare class UnsupportedChainError extends Error {
84
+ readonly code: "UNSUPPORTED_CHAIN";
85
+ readonly chain: string;
86
+ constructor(chain: string);
87
+ }
88
+
89
+ /**
90
+ * The primary entry point for the Awarizon Web3 SDK.
91
+ *
92
+ * ```ts
93
+ * const sdk = new AwarizonWeb3({ chain: "base" })
94
+ *
95
+ * // Internal wallet
96
+ * const wallet = await sdk.wallet.create()
97
+ *
98
+ * // Load a contract and call it
99
+ * const staking = await sdk.contract({ address: "0x...", abi })
100
+ * await staking.stake(100n)
101
+ * const balance = await staking.getBalance(wallet.address)
102
+ *
103
+ * // Listen for events
104
+ * staking.on("Staked", (log) => console.log(log))
105
+ * ```
106
+ */
107
+ declare class AwarizonWeb3 {
108
+ /** The resolved viem Chain */
109
+ readonly chain: Chain;
110
+ /** Internal wallet + signer management */
111
+ readonly wallet: WalletEngine;
112
+ /** The underlying viem PublicClient used for reads */
113
+ readonly publicClient: PublicClient;
114
+ constructor(config: AwarizonConfig);
115
+ /**
116
+ * Connect an external wallet client (wagmi, WalletConnect, viem, EIP-1193).
117
+ * The connected signer takes priority over any internal wallet.
118
+ *
119
+ * @example
120
+ * sdk.connectWallet(walletClient)
121
+ */
122
+ connectWallet(walletClient: WalletClient): this;
123
+ /**
124
+ * Disconnect the externally-connected wallet.
125
+ * Falls back to the internal wallet if one is loaded.
126
+ */
127
+ disconnectWallet(): this;
128
+ /**
129
+ * Switch the active chain.
130
+ * Rebuilds the PublicClient and internal WalletClient for the new chain.
131
+ */
132
+ switchChain(chain: Chain | string): Promise<this>;
133
+ /**
134
+ * Returns a summary of the currently active wallet.
135
+ * @throws {WalletNotConnectedError} if no wallet is connected
136
+ */
137
+ getWalletInfo(): SDKWalletInfo;
138
+ /**
139
+ * Load a deployed smart contract and return a fully typed, ABI-powered
140
+ * instance. Every function in the ABI is exposed as a direct method.
141
+ *
142
+ * **Read functions** (view / pure) use the PublicClient — no signer needed.
143
+ * **Write functions** (nonpayable / payable) use the active WalletClient.
144
+ *
145
+ * @example
146
+ * const token = await sdk.contract({ address: "0x...", abi: ERC20_ABI })
147
+ * const balance = await token.balanceOf(address) // read
148
+ * await token.transfer(to, 100n) // write
149
+ * token.on("Transfer", handler) // events
150
+ */
151
+ contract<TAbi extends Abi>(config: ContractConfig<TAbi>): Promise<ContractInstance>;
152
+ /**
153
+ * Returns the chain ID of the current chain.
154
+ * Useful for runtime network validation.
155
+ */
156
+ get chainId(): number;
157
+ /**
158
+ * Check whether any wallet (internal or external) is connected.
159
+ */
160
+ get isConnected(): boolean;
161
+ }
162
+
163
+ declare const CHAINS: Record<string, Chain>;
164
+ /**
165
+ * Resolves a chain string identifier or a viem Chain object to a Chain.
166
+ *
167
+ * @example
168
+ * resolveChain("base") // → Chain object for Base
169
+ * resolveChain(base) // → same Chain object, passthrough
170
+ * resolveChain("unknown") // → throws Error
171
+ */
172
+ declare function resolveChain(chain: Chain | string): Chain;
173
+ /** Returns a list of all unique supported chain IDs */
174
+ declare function getSupportedChainIds(): number[];
175
+
176
+ export { type AwarizonConfig, AwarizonWeb3, CHAINS, type ContractConfig, type ContractInstance, ContractNotLoadedError, type EventUnsubscribe, NetworkMismatchError, type PayableOptions, ProviderError, type SDKWalletInfo, UnsupportedChainError, getSupportedChainIds, resolveChain };
package/dist/index.js ADDED
@@ -0,0 +1,379 @@
1
+ 'use strict';
2
+
3
+ var viem = require('viem');
4
+ var walletEngine = require('@awarizon/wallet-engine');
5
+ var chains = require('viem/chains');
6
+ var abiEngine = require('@awarizon/abi-engine');
7
+ var txEngine = require('@awarizon/tx-engine');
8
+
9
+ // src/sdk.ts
10
+ var CHAINS = {
11
+ // Mainnet
12
+ mainnet: chains.mainnet,
13
+ ethereum: chains.mainnet,
14
+ eth: chains.mainnet,
15
+ // Base
16
+ base: chains.base,
17
+ "base-mainnet": chains.base,
18
+ // Base Sepolia
19
+ "base-sepolia": chains.baseSepolia,
20
+ baseSepolia: chains.baseSepolia,
21
+ // Polygon
22
+ polygon: chains.polygon,
23
+ matic: chains.polygon,
24
+ // Polygon Amoy (testnet)
25
+ amoy: chains.polygonAmoy,
26
+ "polygon-amoy": chains.polygonAmoy,
27
+ // Arbitrum
28
+ arbitrum: chains.arbitrum,
29
+ "arbitrum-one": chains.arbitrum,
30
+ // Arbitrum Sepolia
31
+ "arbitrum-sepolia": chains.arbitrumSepolia,
32
+ arbitrumSepolia: chains.arbitrumSepolia,
33
+ // Optimism
34
+ optimism: chains.optimism,
35
+ op: chains.optimism,
36
+ // Optimism Sepolia
37
+ "optimism-sepolia": chains.optimismSepolia,
38
+ optimismSepolia: chains.optimismSepolia,
39
+ // BSC
40
+ bsc: chains.bsc,
41
+ bnb: chains.bsc,
42
+ "binance-smart-chain": chains.bsc,
43
+ // Avalanche
44
+ avalanche: chains.avalanche,
45
+ avax: chains.avalanche,
46
+ // Testnets
47
+ sepolia: chains.sepolia,
48
+ "eth-sepolia": chains.sepolia,
49
+ // Other L2s
50
+ zora: chains.zora,
51
+ linea: chains.linea,
52
+ scroll: chains.scroll,
53
+ mantle: chains.mantle,
54
+ celo: chains.celo,
55
+ gnosis: chains.gnosis,
56
+ xdai: chains.gnosis,
57
+ fantom: chains.fantom,
58
+ moonbeam: chains.moonbeam
59
+ };
60
+ function resolveChain(chain) {
61
+ if (typeof chain === "object" && "id" in chain) {
62
+ return chain;
63
+ }
64
+ if (typeof chain === "string") {
65
+ const resolved = CHAINS[chain.toLowerCase()] ?? CHAINS[chain];
66
+ if (!resolved) {
67
+ const available = Object.keys(CHAINS).filter((k, i, arr) => arr.indexOf(k) === i).sort().join(", ");
68
+ throw new Error(
69
+ `[awarizon/web3] Unsupported chain: "${chain}".
70
+ Available chains: ${available}`
71
+ );
72
+ }
73
+ return resolved;
74
+ }
75
+ throw new TypeError(`[awarizon/web3] chain must be a string or Chain object, got: ${typeof chain}`);
76
+ }
77
+ function getSupportedChainIds() {
78
+ const seen = /* @__PURE__ */ new Set();
79
+ return Object.values(CHAINS).filter((c) => {
80
+ if (seen.has(c.id)) return false;
81
+ seen.add(c.id);
82
+ return true;
83
+ }).map((c) => c.id);
84
+ }
85
+ function buildContractInstance(address, abi, publicClient, getWalletClient) {
86
+ const parsed = abiEngine.parseABI(abi);
87
+ const txEngine$1 = new txEngine.TransactionEngine(publicClient, getWalletClient);
88
+ const instance = {
89
+ _address: address,
90
+ _abi: abi
91
+ };
92
+ for (const fn of parsed.readFunctions) {
93
+ instance[fn.name] = buildReadMethod(fn, address, abi, txEngine$1);
94
+ }
95
+ for (const fn of parsed.writeFunctions) {
96
+ instance[fn.name] = buildWriteMethod(fn, address, abi, txEngine$1);
97
+ }
98
+ instance["on"] = buildEventSubscription(address, abi, parsed.events, publicClient);
99
+ instance["estimateGas"] = async (method, ...args) => {
100
+ const estimate = await txEngine$1.estimateGas({
101
+ address,
102
+ abi,
103
+ functionName: method,
104
+ args
105
+ });
106
+ return estimate.gas;
107
+ };
108
+ return instance;
109
+ }
110
+ function buildReadMethod(fn, address, abi, txEngine) {
111
+ return async (...args) => {
112
+ return txEngine.read({ address, abi, functionName: fn.name, args });
113
+ };
114
+ }
115
+ function buildWriteMethod(fn, address, abi, txEngine) {
116
+ const isPayable = fn.stateMutability === "payable";
117
+ return async (...args) => {
118
+ let callArgs = args;
119
+ let value;
120
+ let gas;
121
+ if (isPayable && args.length > 0) {
122
+ const last = args[args.length - 1];
123
+ if (isPayableOptions(last)) {
124
+ callArgs = args.slice(0, -1);
125
+ value = last.value;
126
+ gas = last.gas;
127
+ }
128
+ }
129
+ return txEngine.write({
130
+ address,
131
+ abi,
132
+ functionName: fn.name,
133
+ args: callArgs,
134
+ value,
135
+ gas
136
+ });
137
+ };
138
+ }
139
+ function isPayableOptions(val) {
140
+ if (!val || typeof val !== "object") return false;
141
+ const obj = val;
142
+ const hasValue = "value" in obj && (obj.value === void 0 || typeof obj.value === "bigint");
143
+ const hasGas = "gas" in obj && (obj.gas === void 0 || typeof obj.gas === "bigint");
144
+ return hasValue || hasGas;
145
+ }
146
+ function buildEventSubscription(address, abi, events, publicClient) {
147
+ return (eventName, callback) => {
148
+ const abiEvent = events.find((e) => e.name === eventName);
149
+ if (!abiEvent) {
150
+ const available = events.map((e) => e.name).join(", ") || "none";
151
+ throw new Error(
152
+ `[awarizon/web3] Event "${eventName}" not found on contract ${address}.
153
+ Available events: ${available}`
154
+ );
155
+ }
156
+ const unwatch = publicClient.watchContractEvent({
157
+ address,
158
+ abi,
159
+ eventName,
160
+ onLogs: (logs) => {
161
+ for (const log of logs) callback(log);
162
+ }
163
+ });
164
+ return unwatch;
165
+ };
166
+ }
167
+
168
+ // src/errors.ts
169
+ var NetworkMismatchError = class extends Error {
170
+ constructor(expected, got) {
171
+ super(`[awarizon/web3] Network mismatch: expected chain ID ${expected}, but wallet is on chain ID ${got}`);
172
+ this.code = "NETWORK_MISMATCH";
173
+ this.name = "NetworkMismatchError";
174
+ this.expected = String(expected);
175
+ this.got = String(got);
176
+ }
177
+ };
178
+ var ProviderError = class extends Error {
179
+ constructor(message) {
180
+ super(`[awarizon/web3] Provider error: ${message}`);
181
+ this.code = "PROVIDER_ERROR";
182
+ this.name = "ProviderError";
183
+ }
184
+ };
185
+ var ContractNotLoadedError = class extends Error {
186
+ constructor(address) {
187
+ super(`[awarizon/web3] Contract at ${address} is not loaded. Call sdk.contract({ address, abi }) first.`);
188
+ this.code = "CONTRACT_NOT_LOADED";
189
+ this.name = "ContractNotLoadedError";
190
+ }
191
+ };
192
+ var UnsupportedChainError = class extends Error {
193
+ constructor(chain) {
194
+ super(`[awarizon/web3] Unsupported chain: "${chain}". Pass a valid chain name or viem Chain object.`);
195
+ this.code = "UNSUPPORTED_CHAIN";
196
+ this.name = "UnsupportedChainError";
197
+ this.chain = chain;
198
+ }
199
+ };
200
+
201
+ // src/sdk.ts
202
+ var AwarizonWeb3 = class {
203
+ constructor(config) {
204
+ this.chain = resolveChain(config.chain);
205
+ this.publicClient = viem.createPublicClient({
206
+ chain: this.chain,
207
+ transport: viem.http(config.rpcUrl)
208
+ });
209
+ this.wallet = new walletEngine.WalletEngine({
210
+ chain: this.chain,
211
+ publicClient: this.publicClient,
212
+ rpcUrl: config.rpcUrl
213
+ });
214
+ if (config.signer) {
215
+ this.wallet.connectExternal(config.signer);
216
+ }
217
+ }
218
+ // ─── Wallet API surface ─────────────────────────────────────────────────────
219
+ /**
220
+ * Connect an external wallet client (wagmi, WalletConnect, viem, EIP-1193).
221
+ * The connected signer takes priority over any internal wallet.
222
+ *
223
+ * @example
224
+ * sdk.connectWallet(walletClient)
225
+ */
226
+ connectWallet(walletClient) {
227
+ this.wallet.connectExternal(walletClient);
228
+ return this;
229
+ }
230
+ /**
231
+ * Disconnect the externally-connected wallet.
232
+ * Falls back to the internal wallet if one is loaded.
233
+ */
234
+ disconnectWallet() {
235
+ this.wallet.disconnectExternal();
236
+ return this;
237
+ }
238
+ /**
239
+ * Switch the active chain.
240
+ * Rebuilds the PublicClient and internal WalletClient for the new chain.
241
+ */
242
+ async switchChain(chain) {
243
+ const resolved = resolveChain(chain);
244
+ await this.wallet.switchChain(resolved);
245
+ return this;
246
+ }
247
+ /**
248
+ * Returns a summary of the currently active wallet.
249
+ * @throws {WalletNotConnectedError} if no wallet is connected
250
+ */
251
+ getWalletInfo() {
252
+ return {
253
+ address: this.wallet.address(),
254
+ chain: this.chain,
255
+ isExternal: this.wallet.hasExternalWallet()
256
+ };
257
+ }
258
+ // ─── Contract API ───────────────────────────────────────────────────────────
259
+ /**
260
+ * Load a deployed smart contract and return a fully typed, ABI-powered
261
+ * instance. Every function in the ABI is exposed as a direct method.
262
+ *
263
+ * **Read functions** (view / pure) use the PublicClient — no signer needed.
264
+ * **Write functions** (nonpayable / payable) use the active WalletClient.
265
+ *
266
+ * @example
267
+ * const token = await sdk.contract({ address: "0x...", abi: ERC20_ABI })
268
+ * const balance = await token.balanceOf(address) // read
269
+ * await token.transfer(to, 100n) // write
270
+ * token.on("Transfer", handler) // events
271
+ */
272
+ async contract(config) {
273
+ if (!config.address || !config.abi) {
274
+ throw new Error("[awarizon/web3] sdk.contract() requires both address and abi");
275
+ }
276
+ return buildContractInstance(
277
+ config.address,
278
+ config.abi,
279
+ this.publicClient,
280
+ () => this.wallet.getWalletClient()
281
+ );
282
+ }
283
+ /**
284
+ * Returns the chain ID of the current chain.
285
+ * Useful for runtime network validation.
286
+ */
287
+ get chainId() {
288
+ return this.chain.id;
289
+ }
290
+ /**
291
+ * Check whether any wallet (internal or external) is connected.
292
+ */
293
+ get isConnected() {
294
+ return this.wallet.isConnected();
295
+ }
296
+ };
297
+
298
+ Object.defineProperty(exports, "ChainSwitchError", {
299
+ enumerable: true,
300
+ get: function () { return walletEngine.ChainSwitchError; }
301
+ });
302
+ Object.defineProperty(exports, "InvalidMnemonicError", {
303
+ enumerable: true,
304
+ get: function () { return walletEngine.InvalidMnemonicError; }
305
+ });
306
+ Object.defineProperty(exports, "InvalidPrivateKeyError", {
307
+ enumerable: true,
308
+ get: function () { return walletEngine.InvalidPrivateKeyError; }
309
+ });
310
+ Object.defineProperty(exports, "WalletEngine", {
311
+ enumerable: true,
312
+ get: function () { return walletEngine.WalletEngine; }
313
+ });
314
+ Object.defineProperty(exports, "WalletNotConnectedError", {
315
+ enumerable: true,
316
+ get: function () { return walletEngine.WalletNotConnectedError; }
317
+ });
318
+ Object.defineProperty(exports, "DuplicateFunctionError", {
319
+ enumerable: true,
320
+ get: function () { return abiEngine.DuplicateFunctionError; }
321
+ });
322
+ Object.defineProperty(exports, "InvalidABIError", {
323
+ enumerable: true,
324
+ get: function () { return abiEngine.InvalidABIError; }
325
+ });
326
+ Object.defineProperty(exports, "UnsupportedABIItemError", {
327
+ enumerable: true,
328
+ get: function () { return abiEngine.UnsupportedABIItemError; }
329
+ });
330
+ Object.defineProperty(exports, "generateAllMethodSignatures", {
331
+ enumerable: true,
332
+ get: function () { return abiEngine.generateAllMethodSignatures; }
333
+ });
334
+ Object.defineProperty(exports, "generateMethodSignature", {
335
+ enumerable: true,
336
+ get: function () { return abiEngine.generateMethodSignature; }
337
+ });
338
+ Object.defineProperty(exports, "isPayableFunction", {
339
+ enumerable: true,
340
+ get: function () { return abiEngine.isPayableFunction; }
341
+ });
342
+ Object.defineProperty(exports, "isWriteFunction", {
343
+ enumerable: true,
344
+ get: function () { return abiEngine.isWriteFunction; }
345
+ });
346
+ Object.defineProperty(exports, "parseABI", {
347
+ enumerable: true,
348
+ get: function () { return abiEngine.parseABI; }
349
+ });
350
+ Object.defineProperty(exports, "ContractExecutionError", {
351
+ enumerable: true,
352
+ get: function () { return txEngine.ContractExecutionError; }
353
+ });
354
+ Object.defineProperty(exports, "GasEstimationError", {
355
+ enumerable: true,
356
+ get: function () { return txEngine.GasEstimationError; }
357
+ });
358
+ Object.defineProperty(exports, "SimulationError", {
359
+ enumerable: true,
360
+ get: function () { return txEngine.SimulationError; }
361
+ });
362
+ Object.defineProperty(exports, "TransactionEngine", {
363
+ enumerable: true,
364
+ get: function () { return txEngine.TransactionEngine; }
365
+ });
366
+ Object.defineProperty(exports, "TransactionTimeoutError", {
367
+ enumerable: true,
368
+ get: function () { return txEngine.TransactionTimeoutError; }
369
+ });
370
+ exports.AwarizonWeb3 = AwarizonWeb3;
371
+ exports.CHAINS = CHAINS;
372
+ exports.ContractNotLoadedError = ContractNotLoadedError;
373
+ exports.NetworkMismatchError = NetworkMismatchError;
374
+ exports.ProviderError = ProviderError;
375
+ exports.UnsupportedChainError = UnsupportedChainError;
376
+ exports.getSupportedChainIds = getSupportedChainIds;
377
+ exports.resolveChain = resolveChain;
378
+ //# sourceMappingURL=index.js.map
379
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chains.ts","../src/contract.ts","../src/errors.ts","../src/sdk.ts"],"names":["mainnet","base","baseSepolia","polygon","polygonAmoy","arbitrum","arbitrumSepolia","optimism","optimismSepolia","bsc","avalanche","sepolia","zora","linea","scroll","mantle","celo","gnosis","fantom","moonbeam","parseABI","txEngine","TransactionEngine","createPublicClient","http","WalletEngine"],"mappings":"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","file":"index.js","sourcesContent":["import {\n mainnet,\n base,\n baseSepolia,\n polygon,\n polygonAmoy,\n arbitrum,\n arbitrumSepolia,\n optimism,\n optimismSepolia,\n bsc,\n avalanche,\n sepolia,\n zora,\n linea,\n scroll,\n mantle,\n celo,\n gnosis,\n fantom,\n moonbeam,\n} from 'viem/chains';\nimport type { Chain } from 'viem';\n\n// ─── Supported chains registry ────────────────────────────────────────────────\n\nexport const CHAINS: Record<string, Chain> = {\n // Mainnet\n mainnet,\n ethereum: mainnet,\n eth: mainnet,\n\n // Base\n base,\n 'base-mainnet': base,\n\n // Base Sepolia\n 'base-sepolia': baseSepolia,\n baseSepolia,\n\n // Polygon\n polygon,\n matic: polygon,\n\n // Polygon Amoy (testnet)\n amoy: polygonAmoy,\n 'polygon-amoy': polygonAmoy,\n\n // Arbitrum\n arbitrum,\n 'arbitrum-one': arbitrum,\n\n // Arbitrum Sepolia\n 'arbitrum-sepolia': arbitrumSepolia,\n arbitrumSepolia,\n\n // Optimism\n optimism,\n op: optimism,\n\n // Optimism Sepolia\n 'optimism-sepolia': optimismSepolia,\n optimismSepolia,\n\n // BSC\n bsc,\n bnb: bsc,\n 'binance-smart-chain': bsc,\n\n // Avalanche\n avalanche,\n avax: avalanche,\n\n // Testnets\n sepolia,\n 'eth-sepolia': sepolia,\n\n // Other L2s\n zora,\n linea,\n scroll,\n mantle,\n celo,\n gnosis,\n xdai: gnosis,\n fantom,\n moonbeam,\n};\n\n// ─── Helper ───────────────────────────────────────────────────────────────────\n\n/**\n * Resolves a chain string identifier or a viem Chain object to a Chain.\n *\n * @example\n * resolveChain(\"base\") // → Chain object for Base\n * resolveChain(base) // → same Chain object, passthrough\n * resolveChain(\"unknown\") // → throws Error\n */\nexport function resolveChain(chain: Chain | string): Chain {\n if (typeof chain === 'object' && 'id' in chain) {\n return chain;\n }\n\n if (typeof chain === 'string') {\n const resolved = CHAINS[chain.toLowerCase()] ?? CHAINS[chain];\n if (!resolved) {\n const available = Object.keys(CHAINS)\n .filter((k, i, arr) => arr.indexOf(k) === i) // deduplicate aliases\n .sort()\n .join(', ');\n throw new Error(\n `[awarizon/web3] Unsupported chain: \"${chain}\".\\n` +\n `Available chains: ${available}`,\n );\n }\n return resolved;\n }\n\n throw new TypeError(`[awarizon/web3] chain must be a string or Chain object, got: ${typeof chain}`);\n}\n\n/** Returns a list of all unique supported chain IDs */\nexport function getSupportedChainIds(): number[] {\n const seen = new Set<number>();\n return Object.values(CHAINS)\n .filter(c => { if (seen.has(c.id)) return false; seen.add(c.id); return true; })\n .map(c => c.id);\n}\n","import type { Abi, AbiFunction, AbiEvent, Address, PublicClient, WalletClient } from 'viem';\nimport { parseABI, isWriteFunction } from '@awarizon/abi-engine';\nimport { TransactionEngine } from '@awarizon/tx-engine';\nimport type { ContractInstance, EventUnsubscribe } from './types';\n\n// ─── ContractFactory ──────────────────────────────────────────────────────────\n\n/**\n * Builds a fully dynamic ContractInstance from an address + ABI.\n *\n * For every function in the ABI it attaches a method to the returned\n * object that automatically routes to read or write depending on the\n * function's stateMutability.\n *\n * Additionally exposes:\n * .on(event, callback) – event subscription\n * .estimateGas(method, ...args) – gas estimation\n * ._address / ._abi – metadata accessors\n */\nexport function buildContractInstance(\n address: Address,\n abi: Abi,\n publicClient: PublicClient,\n getWalletClient: () => WalletClient,\n): ContractInstance {\n const parsed = parseABI(abi);\n const txEngine = new TransactionEngine(publicClient, getWalletClient);\n\n // ── Base object ─────────────────────────────────────────────────────────────\n const instance: Record<string, unknown> = {\n _address: address,\n _abi: abi,\n };\n\n // ── Generate read methods ───────────────────────────────────────────────────\n for (const fn of parsed.readFunctions) {\n instance[fn.name] = buildReadMethod(fn, address, abi, txEngine);\n }\n\n // ── Generate write methods ──────────────────────────────────────────────────\n for (const fn of parsed.writeFunctions) {\n instance[fn.name] = buildWriteMethod(fn, address, abi, txEngine);\n }\n\n // ── Event subscription ──────────────────────────────────────────────────────\n instance['on'] = buildEventSubscription(address, abi, parsed.events, publicClient);\n\n // ── Gas estimation ──────────────────────────────────────────────────────────\n instance['estimateGas'] = async (method: string, ...args: unknown[]): Promise<bigint> => {\n const estimate = await txEngine.estimateGas({\n address,\n abi,\n functionName: method,\n args,\n });\n return estimate.gas;\n };\n\n return instance as ContractInstance;\n}\n\n// ─── Read method builder ──────────────────────────────────────────────────────\n\nfunction buildReadMethod(\n fn: AbiFunction,\n address: Address,\n abi: Abi,\n txEngine: TransactionEngine,\n): (...args: unknown[]) => Promise<unknown> {\n return async (...args: unknown[]) => {\n return txEngine.read({ address, abi, functionName: fn.name, args });\n };\n}\n\n// ─── Write method builder ─────────────────────────────────────────────────────\n\nfunction buildWriteMethod(\n fn: AbiFunction,\n address: Address,\n abi: Abi,\n txEngine: TransactionEngine,\n): (...args: unknown[]) => Promise<unknown> {\n const isPayable = fn.stateMutability === 'payable';\n\n return async (...args: unknown[]) => {\n // Payable functions accept an optional trailing options object\n let callArgs = args;\n let value: bigint | undefined;\n let gas: bigint | undefined;\n\n if (isPayable && args.length > 0) {\n const last = args[args.length - 1];\n if (isPayableOptions(last)) {\n callArgs = args.slice(0, -1);\n value = last.value;\n gas = last.gas;\n }\n }\n\n return txEngine.write({\n address,\n abi,\n functionName: fn.name,\n args: callArgs,\n value,\n gas,\n });\n };\n}\n\nfunction isPayableOptions(val: unknown): val is { value?: bigint; gas?: bigint } {\n if (!val || typeof val !== 'object') return false;\n const obj = val as Record<string, unknown>;\n const hasValue = 'value' in obj && (obj.value === undefined || typeof obj.value === 'bigint');\n const hasGas = 'gas' in obj && (obj.gas === undefined || typeof obj.gas === 'bigint');\n return hasValue || hasGas;\n}\n\n// ─── Event subscription builder ───────────────────────────────────────────────\n\nfunction buildEventSubscription(\n address: Address,\n abi: Abi,\n events: AbiEvent[],\n publicClient: PublicClient,\n): (event: string, callback: (log: unknown) => void) => EventUnsubscribe {\n return (eventName: string, callback: (log: unknown) => void): EventUnsubscribe => {\n const abiEvent = events.find(e => e.name === eventName);\n\n if (!abiEvent) {\n const available = events.map(e => e.name).join(', ') || 'none';\n throw new Error(\n `[awarizon/web3] Event \"${eventName}\" not found on contract ${address}.\\n` +\n `Available events: ${available}`,\n );\n }\n\n const unwatch = publicClient.watchContractEvent({\n address,\n abi,\n eventName,\n onLogs: (logs) => {\n for (const log of logs) callback(log);\n },\n });\n\n return unwatch;\n };\n}\n","export class NetworkMismatchError extends Error {\n readonly code = 'NETWORK_MISMATCH' as const;\n readonly expected: string;\n readonly got: string;\n\n constructor(expected: string | number, got: string | number) {\n super(`[awarizon/web3] Network mismatch: expected chain ID ${expected}, but wallet is on chain ID ${got}`);\n this.name = 'NetworkMismatchError';\n this.expected = String(expected);\n this.got = String(got);\n }\n}\n\nexport class ProviderError extends Error {\n readonly code = 'PROVIDER_ERROR' as const;\n\n constructor(message: string) {\n super(`[awarizon/web3] Provider error: ${message}`);\n this.name = 'ProviderError';\n }\n}\n\nexport class ContractNotLoadedError extends Error {\n readonly code = 'CONTRACT_NOT_LOADED' as const;\n\n constructor(address: string) {\n super(`[awarizon/web3] Contract at ${address} is not loaded. Call sdk.contract({ address, abi }) first.`);\n this.name = 'ContractNotLoadedError';\n }\n}\n\nexport class UnsupportedChainError extends Error {\n readonly code = 'UNSUPPORTED_CHAIN' as const;\n readonly chain: string;\n\n constructor(chain: string) {\n super(`[awarizon/web3] Unsupported chain: \"${chain}\". Pass a valid chain name or viem Chain object.`);\n this.name = 'UnsupportedChainError';\n this.chain = chain;\n }\n}\n","import {\n createPublicClient,\n http,\n type Chain,\n type WalletClient,\n type PublicClient,\n type Address,\n type Abi,\n} from 'viem';\nimport { WalletEngine } from '@awarizon/wallet-engine';\nimport { resolveChain } from './chains';\nimport { buildContractInstance } from './contract';\nimport type {\n AwarizonConfig,\n ContractConfig,\n ContractInstance,\n SDKWalletInfo,\n} from './types';\n\n// Re-export errors for convenience so consumers don't need extra imports\nexport {\n WalletNotConnectedError,\n InvalidMnemonicError,\n InvalidPrivateKeyError,\n} from '@awarizon/wallet-engine';\n\nexport {\n ContractExecutionError,\n SimulationError,\n GasEstimationError,\n} from '@awarizon/tx-engine';\n\nexport {\n InvalidABIError,\n} from '@awarizon/abi-engine';\n\nexport {\n NetworkMismatchError,\n ProviderError,\n ContractNotLoadedError,\n UnsupportedChainError,\n} from './errors';\n\n// ─── AwarizonWeb3 ─────────────────────────────────────────────────────────────\n\n/**\n * The primary entry point for the Awarizon Web3 SDK.\n *\n * ```ts\n * const sdk = new AwarizonWeb3({ chain: \"base\" })\n *\n * // Internal wallet\n * const wallet = await sdk.wallet.create()\n *\n * // Load a contract and call it\n * const staking = await sdk.contract({ address: \"0x...\", abi })\n * await staking.stake(100n)\n * const balance = await staking.getBalance(wallet.address)\n *\n * // Listen for events\n * staking.on(\"Staked\", (log) => console.log(log))\n * ```\n */\nexport class AwarizonWeb3 {\n /** The resolved viem Chain */\n readonly chain: Chain;\n\n /** Internal wallet + signer management */\n readonly wallet: WalletEngine;\n\n /** The underlying viem PublicClient used for reads */\n readonly publicClient: PublicClient;\n\n constructor(config: AwarizonConfig) {\n this.chain = resolveChain(config.chain);\n\n this.publicClient = createPublicClient({\n chain: this.chain,\n transport: http(config.rpcUrl),\n });\n\n this.wallet = new WalletEngine({\n chain: this.chain,\n publicClient: this.publicClient,\n rpcUrl: config.rpcUrl,\n });\n\n // Pre-connect external signer if provided at construction time\n if (config.signer) {\n this.wallet.connectExternal(config.signer);\n }\n }\n\n // ─── Wallet API surface ─────────────────────────────────────────────────────\n\n /**\n * Connect an external wallet client (wagmi, WalletConnect, viem, EIP-1193).\n * The connected signer takes priority over any internal wallet.\n *\n * @example\n * sdk.connectWallet(walletClient)\n */\n connectWallet(walletClient: WalletClient): this {\n this.wallet.connectExternal(walletClient);\n return this;\n }\n\n /**\n * Disconnect the externally-connected wallet.\n * Falls back to the internal wallet if one is loaded.\n */\n disconnectWallet(): this {\n this.wallet.disconnectExternal();\n return this;\n }\n\n /**\n * Switch the active chain.\n * Rebuilds the PublicClient and internal WalletClient for the new chain.\n */\n async switchChain(chain: Chain | string): Promise<this> {\n const resolved = resolveChain(chain);\n await this.wallet.switchChain(resolved);\n return this;\n }\n\n /**\n * Returns a summary of the currently active wallet.\n * @throws {WalletNotConnectedError} if no wallet is connected\n */\n getWalletInfo(): SDKWalletInfo {\n return {\n address: this.wallet.address(),\n chain: this.chain,\n isExternal: this.wallet.hasExternalWallet(),\n };\n }\n\n // ─── Contract API ───────────────────────────────────────────────────────────\n\n /**\n * Load a deployed smart contract and return a fully typed, ABI-powered\n * instance. Every function in the ABI is exposed as a direct method.\n *\n * **Read functions** (view / pure) use the PublicClient — no signer needed.\n * **Write functions** (nonpayable / payable) use the active WalletClient.\n *\n * @example\n * const token = await sdk.contract({ address: \"0x...\", abi: ERC20_ABI })\n * const balance = await token.balanceOf(address) // read\n * await token.transfer(to, 100n) // write\n * token.on(\"Transfer\", handler) // events\n */\n async contract<TAbi extends Abi>(config: ContractConfig<TAbi>): Promise<ContractInstance> {\n if (!config.address || !config.abi) {\n throw new Error('[awarizon/web3] sdk.contract() requires both address and abi');\n }\n\n return buildContractInstance(\n config.address,\n config.abi as Abi,\n this.publicClient,\n () => this.wallet.getWalletClient(),\n );\n }\n\n /**\n * Returns the chain ID of the current chain.\n * Useful for runtime network validation.\n */\n get chainId(): number {\n return this.chain.id;\n }\n\n /**\n * Check whether any wallet (internal or external) is connected.\n */\n get isConnected(): boolean {\n return this.wallet.isConnected();\n }\n}\n"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,301 @@
1
+ import { createPublicClient, http } from 'viem';
2
+ import { WalletEngine } from '@awarizon/wallet-engine';
3
+ export { ChainSwitchError, InvalidMnemonicError, InvalidPrivateKeyError, WalletEngine, WalletNotConnectedError } from '@awarizon/wallet-engine';
4
+ import { moonbeam, fantom, gnosis, celo, mantle, scroll, linea, zora, sepolia, avalanche, bsc, optimismSepolia, optimism, arbitrumSepolia, arbitrum, polygonAmoy, polygon, baseSepolia, base, mainnet } from 'viem/chains';
5
+ import { parseABI } from '@awarizon/abi-engine';
6
+ export { DuplicateFunctionError, InvalidABIError, UnsupportedABIItemError, generateAllMethodSignatures, generateMethodSignature, isPayableFunction, isWriteFunction, parseABI } from '@awarizon/abi-engine';
7
+ import { TransactionEngine } from '@awarizon/tx-engine';
8
+ export { ContractExecutionError, GasEstimationError, SimulationError, TransactionEngine, TransactionTimeoutError } from '@awarizon/tx-engine';
9
+
10
+ // src/sdk.ts
11
+ var CHAINS = {
12
+ // Mainnet
13
+ mainnet,
14
+ ethereum: mainnet,
15
+ eth: mainnet,
16
+ // Base
17
+ base,
18
+ "base-mainnet": base,
19
+ // Base Sepolia
20
+ "base-sepolia": baseSepolia,
21
+ baseSepolia,
22
+ // Polygon
23
+ polygon,
24
+ matic: polygon,
25
+ // Polygon Amoy (testnet)
26
+ amoy: polygonAmoy,
27
+ "polygon-amoy": polygonAmoy,
28
+ // Arbitrum
29
+ arbitrum,
30
+ "arbitrum-one": arbitrum,
31
+ // Arbitrum Sepolia
32
+ "arbitrum-sepolia": arbitrumSepolia,
33
+ arbitrumSepolia,
34
+ // Optimism
35
+ optimism,
36
+ op: optimism,
37
+ // Optimism Sepolia
38
+ "optimism-sepolia": optimismSepolia,
39
+ optimismSepolia,
40
+ // BSC
41
+ bsc,
42
+ bnb: bsc,
43
+ "binance-smart-chain": bsc,
44
+ // Avalanche
45
+ avalanche,
46
+ avax: avalanche,
47
+ // Testnets
48
+ sepolia,
49
+ "eth-sepolia": sepolia,
50
+ // Other L2s
51
+ zora,
52
+ linea,
53
+ scroll,
54
+ mantle,
55
+ celo,
56
+ gnosis,
57
+ xdai: gnosis,
58
+ fantom,
59
+ moonbeam
60
+ };
61
+ function resolveChain(chain) {
62
+ if (typeof chain === "object" && "id" in chain) {
63
+ return chain;
64
+ }
65
+ if (typeof chain === "string") {
66
+ const resolved = CHAINS[chain.toLowerCase()] ?? CHAINS[chain];
67
+ if (!resolved) {
68
+ const available = Object.keys(CHAINS).filter((k, i, arr) => arr.indexOf(k) === i).sort().join(", ");
69
+ throw new Error(
70
+ `[awarizon/web3] Unsupported chain: "${chain}".
71
+ Available chains: ${available}`
72
+ );
73
+ }
74
+ return resolved;
75
+ }
76
+ throw new TypeError(`[awarizon/web3] chain must be a string or Chain object, got: ${typeof chain}`);
77
+ }
78
+ function getSupportedChainIds() {
79
+ const seen = /* @__PURE__ */ new Set();
80
+ return Object.values(CHAINS).filter((c) => {
81
+ if (seen.has(c.id)) return false;
82
+ seen.add(c.id);
83
+ return true;
84
+ }).map((c) => c.id);
85
+ }
86
+ function buildContractInstance(address, abi, publicClient, getWalletClient) {
87
+ const parsed = parseABI(abi);
88
+ const txEngine = new TransactionEngine(publicClient, getWalletClient);
89
+ const instance = {
90
+ _address: address,
91
+ _abi: abi
92
+ };
93
+ for (const fn of parsed.readFunctions) {
94
+ instance[fn.name] = buildReadMethod(fn, address, abi, txEngine);
95
+ }
96
+ for (const fn of parsed.writeFunctions) {
97
+ instance[fn.name] = buildWriteMethod(fn, address, abi, txEngine);
98
+ }
99
+ instance["on"] = buildEventSubscription(address, abi, parsed.events, publicClient);
100
+ instance["estimateGas"] = async (method, ...args) => {
101
+ const estimate = await txEngine.estimateGas({
102
+ address,
103
+ abi,
104
+ functionName: method,
105
+ args
106
+ });
107
+ return estimate.gas;
108
+ };
109
+ return instance;
110
+ }
111
+ function buildReadMethod(fn, address, abi, txEngine) {
112
+ return async (...args) => {
113
+ return txEngine.read({ address, abi, functionName: fn.name, args });
114
+ };
115
+ }
116
+ function buildWriteMethod(fn, address, abi, txEngine) {
117
+ const isPayable = fn.stateMutability === "payable";
118
+ return async (...args) => {
119
+ let callArgs = args;
120
+ let value;
121
+ let gas;
122
+ if (isPayable && args.length > 0) {
123
+ const last = args[args.length - 1];
124
+ if (isPayableOptions(last)) {
125
+ callArgs = args.slice(0, -1);
126
+ value = last.value;
127
+ gas = last.gas;
128
+ }
129
+ }
130
+ return txEngine.write({
131
+ address,
132
+ abi,
133
+ functionName: fn.name,
134
+ args: callArgs,
135
+ value,
136
+ gas
137
+ });
138
+ };
139
+ }
140
+ function isPayableOptions(val) {
141
+ if (!val || typeof val !== "object") return false;
142
+ const obj = val;
143
+ const hasValue = "value" in obj && (obj.value === void 0 || typeof obj.value === "bigint");
144
+ const hasGas = "gas" in obj && (obj.gas === void 0 || typeof obj.gas === "bigint");
145
+ return hasValue || hasGas;
146
+ }
147
+ function buildEventSubscription(address, abi, events, publicClient) {
148
+ return (eventName, callback) => {
149
+ const abiEvent = events.find((e) => e.name === eventName);
150
+ if (!abiEvent) {
151
+ const available = events.map((e) => e.name).join(", ") || "none";
152
+ throw new Error(
153
+ `[awarizon/web3] Event "${eventName}" not found on contract ${address}.
154
+ Available events: ${available}`
155
+ );
156
+ }
157
+ const unwatch = publicClient.watchContractEvent({
158
+ address,
159
+ abi,
160
+ eventName,
161
+ onLogs: (logs) => {
162
+ for (const log of logs) callback(log);
163
+ }
164
+ });
165
+ return unwatch;
166
+ };
167
+ }
168
+
169
+ // src/errors.ts
170
+ var NetworkMismatchError = class extends Error {
171
+ constructor(expected, got) {
172
+ super(`[awarizon/web3] Network mismatch: expected chain ID ${expected}, but wallet is on chain ID ${got}`);
173
+ this.code = "NETWORK_MISMATCH";
174
+ this.name = "NetworkMismatchError";
175
+ this.expected = String(expected);
176
+ this.got = String(got);
177
+ }
178
+ };
179
+ var ProviderError = class extends Error {
180
+ constructor(message) {
181
+ super(`[awarizon/web3] Provider error: ${message}`);
182
+ this.code = "PROVIDER_ERROR";
183
+ this.name = "ProviderError";
184
+ }
185
+ };
186
+ var ContractNotLoadedError = class extends Error {
187
+ constructor(address) {
188
+ super(`[awarizon/web3] Contract at ${address} is not loaded. Call sdk.contract({ address, abi }) first.`);
189
+ this.code = "CONTRACT_NOT_LOADED";
190
+ this.name = "ContractNotLoadedError";
191
+ }
192
+ };
193
+ var UnsupportedChainError = class extends Error {
194
+ constructor(chain) {
195
+ super(`[awarizon/web3] Unsupported chain: "${chain}". Pass a valid chain name or viem Chain object.`);
196
+ this.code = "UNSUPPORTED_CHAIN";
197
+ this.name = "UnsupportedChainError";
198
+ this.chain = chain;
199
+ }
200
+ };
201
+
202
+ // src/sdk.ts
203
+ var AwarizonWeb3 = class {
204
+ constructor(config) {
205
+ this.chain = resolveChain(config.chain);
206
+ this.publicClient = createPublicClient({
207
+ chain: this.chain,
208
+ transport: http(config.rpcUrl)
209
+ });
210
+ this.wallet = new WalletEngine({
211
+ chain: this.chain,
212
+ publicClient: this.publicClient,
213
+ rpcUrl: config.rpcUrl
214
+ });
215
+ if (config.signer) {
216
+ this.wallet.connectExternal(config.signer);
217
+ }
218
+ }
219
+ // ─── Wallet API surface ─────────────────────────────────────────────────────
220
+ /**
221
+ * Connect an external wallet client (wagmi, WalletConnect, viem, EIP-1193).
222
+ * The connected signer takes priority over any internal wallet.
223
+ *
224
+ * @example
225
+ * sdk.connectWallet(walletClient)
226
+ */
227
+ connectWallet(walletClient) {
228
+ this.wallet.connectExternal(walletClient);
229
+ return this;
230
+ }
231
+ /**
232
+ * Disconnect the externally-connected wallet.
233
+ * Falls back to the internal wallet if one is loaded.
234
+ */
235
+ disconnectWallet() {
236
+ this.wallet.disconnectExternal();
237
+ return this;
238
+ }
239
+ /**
240
+ * Switch the active chain.
241
+ * Rebuilds the PublicClient and internal WalletClient for the new chain.
242
+ */
243
+ async switchChain(chain) {
244
+ const resolved = resolveChain(chain);
245
+ await this.wallet.switchChain(resolved);
246
+ return this;
247
+ }
248
+ /**
249
+ * Returns a summary of the currently active wallet.
250
+ * @throws {WalletNotConnectedError} if no wallet is connected
251
+ */
252
+ getWalletInfo() {
253
+ return {
254
+ address: this.wallet.address(),
255
+ chain: this.chain,
256
+ isExternal: this.wallet.hasExternalWallet()
257
+ };
258
+ }
259
+ // ─── Contract API ───────────────────────────────────────────────────────────
260
+ /**
261
+ * Load a deployed smart contract and return a fully typed, ABI-powered
262
+ * instance. Every function in the ABI is exposed as a direct method.
263
+ *
264
+ * **Read functions** (view / pure) use the PublicClient — no signer needed.
265
+ * **Write functions** (nonpayable / payable) use the active WalletClient.
266
+ *
267
+ * @example
268
+ * const token = await sdk.contract({ address: "0x...", abi: ERC20_ABI })
269
+ * const balance = await token.balanceOf(address) // read
270
+ * await token.transfer(to, 100n) // write
271
+ * token.on("Transfer", handler) // events
272
+ */
273
+ async contract(config) {
274
+ if (!config.address || !config.abi) {
275
+ throw new Error("[awarizon/web3] sdk.contract() requires both address and abi");
276
+ }
277
+ return buildContractInstance(
278
+ config.address,
279
+ config.abi,
280
+ this.publicClient,
281
+ () => this.wallet.getWalletClient()
282
+ );
283
+ }
284
+ /**
285
+ * Returns the chain ID of the current chain.
286
+ * Useful for runtime network validation.
287
+ */
288
+ get chainId() {
289
+ return this.chain.id;
290
+ }
291
+ /**
292
+ * Check whether any wallet (internal or external) is connected.
293
+ */
294
+ get isConnected() {
295
+ return this.wallet.isConnected();
296
+ }
297
+ };
298
+
299
+ export { AwarizonWeb3, CHAINS, ContractNotLoadedError, NetworkMismatchError, ProviderError, UnsupportedChainError, getSupportedChainIds, resolveChain };
300
+ //# sourceMappingURL=index.mjs.map
301
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chains.ts","../src/contract.ts","../src/errors.ts","../src/sdk.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import {\n mainnet,\n base,\n baseSepolia,\n polygon,\n polygonAmoy,\n arbitrum,\n arbitrumSepolia,\n optimism,\n optimismSepolia,\n bsc,\n avalanche,\n sepolia,\n zora,\n linea,\n scroll,\n mantle,\n celo,\n gnosis,\n fantom,\n moonbeam,\n} from 'viem/chains';\nimport type { Chain } from 'viem';\n\n// ─── Supported chains registry ────────────────────────────────────────────────\n\nexport const CHAINS: Record<string, Chain> = {\n // Mainnet\n mainnet,\n ethereum: mainnet,\n eth: mainnet,\n\n // Base\n base,\n 'base-mainnet': base,\n\n // Base Sepolia\n 'base-sepolia': baseSepolia,\n baseSepolia,\n\n // Polygon\n polygon,\n matic: polygon,\n\n // Polygon Amoy (testnet)\n amoy: polygonAmoy,\n 'polygon-amoy': polygonAmoy,\n\n // Arbitrum\n arbitrum,\n 'arbitrum-one': arbitrum,\n\n // Arbitrum Sepolia\n 'arbitrum-sepolia': arbitrumSepolia,\n arbitrumSepolia,\n\n // Optimism\n optimism,\n op: optimism,\n\n // Optimism Sepolia\n 'optimism-sepolia': optimismSepolia,\n optimismSepolia,\n\n // BSC\n bsc,\n bnb: bsc,\n 'binance-smart-chain': bsc,\n\n // Avalanche\n avalanche,\n avax: avalanche,\n\n // Testnets\n sepolia,\n 'eth-sepolia': sepolia,\n\n // Other L2s\n zora,\n linea,\n scroll,\n mantle,\n celo,\n gnosis,\n xdai: gnosis,\n fantom,\n moonbeam,\n};\n\n// ─── Helper ───────────────────────────────────────────────────────────────────\n\n/**\n * Resolves a chain string identifier or a viem Chain object to a Chain.\n *\n * @example\n * resolveChain(\"base\") // → Chain object for Base\n * resolveChain(base) // → same Chain object, passthrough\n * resolveChain(\"unknown\") // → throws Error\n */\nexport function resolveChain(chain: Chain | string): Chain {\n if (typeof chain === 'object' && 'id' in chain) {\n return chain;\n }\n\n if (typeof chain === 'string') {\n const resolved = CHAINS[chain.toLowerCase()] ?? CHAINS[chain];\n if (!resolved) {\n const available = Object.keys(CHAINS)\n .filter((k, i, arr) => arr.indexOf(k) === i) // deduplicate aliases\n .sort()\n .join(', ');\n throw new Error(\n `[awarizon/web3] Unsupported chain: \"${chain}\".\\n` +\n `Available chains: ${available}`,\n );\n }\n return resolved;\n }\n\n throw new TypeError(`[awarizon/web3] chain must be a string or Chain object, got: ${typeof chain}`);\n}\n\n/** Returns a list of all unique supported chain IDs */\nexport function getSupportedChainIds(): number[] {\n const seen = new Set<number>();\n return Object.values(CHAINS)\n .filter(c => { if (seen.has(c.id)) return false; seen.add(c.id); return true; })\n .map(c => c.id);\n}\n","import type { Abi, AbiFunction, AbiEvent, Address, PublicClient, WalletClient } from 'viem';\nimport { parseABI, isWriteFunction } from '@awarizon/abi-engine';\nimport { TransactionEngine } from '@awarizon/tx-engine';\nimport type { ContractInstance, EventUnsubscribe } from './types';\n\n// ─── ContractFactory ──────────────────────────────────────────────────────────\n\n/**\n * Builds a fully dynamic ContractInstance from an address + ABI.\n *\n * For every function in the ABI it attaches a method to the returned\n * object that automatically routes to read or write depending on the\n * function's stateMutability.\n *\n * Additionally exposes:\n * .on(event, callback) – event subscription\n * .estimateGas(method, ...args) – gas estimation\n * ._address / ._abi – metadata accessors\n */\nexport function buildContractInstance(\n address: Address,\n abi: Abi,\n publicClient: PublicClient,\n getWalletClient: () => WalletClient,\n): ContractInstance {\n const parsed = parseABI(abi);\n const txEngine = new TransactionEngine(publicClient, getWalletClient);\n\n // ── Base object ─────────────────────────────────────────────────────────────\n const instance: Record<string, unknown> = {\n _address: address,\n _abi: abi,\n };\n\n // ── Generate read methods ───────────────────────────────────────────────────\n for (const fn of parsed.readFunctions) {\n instance[fn.name] = buildReadMethod(fn, address, abi, txEngine);\n }\n\n // ── Generate write methods ──────────────────────────────────────────────────\n for (const fn of parsed.writeFunctions) {\n instance[fn.name] = buildWriteMethod(fn, address, abi, txEngine);\n }\n\n // ── Event subscription ──────────────────────────────────────────────────────\n instance['on'] = buildEventSubscription(address, abi, parsed.events, publicClient);\n\n // ── Gas estimation ──────────────────────────────────────────────────────────\n instance['estimateGas'] = async (method: string, ...args: unknown[]): Promise<bigint> => {\n const estimate = await txEngine.estimateGas({\n address,\n abi,\n functionName: method,\n args,\n });\n return estimate.gas;\n };\n\n return instance as ContractInstance;\n}\n\n// ─── Read method builder ──────────────────────────────────────────────────────\n\nfunction buildReadMethod(\n fn: AbiFunction,\n address: Address,\n abi: Abi,\n txEngine: TransactionEngine,\n): (...args: unknown[]) => Promise<unknown> {\n return async (...args: unknown[]) => {\n return txEngine.read({ address, abi, functionName: fn.name, args });\n };\n}\n\n// ─── Write method builder ─────────────────────────────────────────────────────\n\nfunction buildWriteMethod(\n fn: AbiFunction,\n address: Address,\n abi: Abi,\n txEngine: TransactionEngine,\n): (...args: unknown[]) => Promise<unknown> {\n const isPayable = fn.stateMutability === 'payable';\n\n return async (...args: unknown[]) => {\n // Payable functions accept an optional trailing options object\n let callArgs = args;\n let value: bigint | undefined;\n let gas: bigint | undefined;\n\n if (isPayable && args.length > 0) {\n const last = args[args.length - 1];\n if (isPayableOptions(last)) {\n callArgs = args.slice(0, -1);\n value = last.value;\n gas = last.gas;\n }\n }\n\n return txEngine.write({\n address,\n abi,\n functionName: fn.name,\n args: callArgs,\n value,\n gas,\n });\n };\n}\n\nfunction isPayableOptions(val: unknown): val is { value?: bigint; gas?: bigint } {\n if (!val || typeof val !== 'object') return false;\n const obj = val as Record<string, unknown>;\n const hasValue = 'value' in obj && (obj.value === undefined || typeof obj.value === 'bigint');\n const hasGas = 'gas' in obj && (obj.gas === undefined || typeof obj.gas === 'bigint');\n return hasValue || hasGas;\n}\n\n// ─── Event subscription builder ───────────────────────────────────────────────\n\nfunction buildEventSubscription(\n address: Address,\n abi: Abi,\n events: AbiEvent[],\n publicClient: PublicClient,\n): (event: string, callback: (log: unknown) => void) => EventUnsubscribe {\n return (eventName: string, callback: (log: unknown) => void): EventUnsubscribe => {\n const abiEvent = events.find(e => e.name === eventName);\n\n if (!abiEvent) {\n const available = events.map(e => e.name).join(', ') || 'none';\n throw new Error(\n `[awarizon/web3] Event \"${eventName}\" not found on contract ${address}.\\n` +\n `Available events: ${available}`,\n );\n }\n\n const unwatch = publicClient.watchContractEvent({\n address,\n abi,\n eventName,\n onLogs: (logs) => {\n for (const log of logs) callback(log);\n },\n });\n\n return unwatch;\n };\n}\n","export class NetworkMismatchError extends Error {\n readonly code = 'NETWORK_MISMATCH' as const;\n readonly expected: string;\n readonly got: string;\n\n constructor(expected: string | number, got: string | number) {\n super(`[awarizon/web3] Network mismatch: expected chain ID ${expected}, but wallet is on chain ID ${got}`);\n this.name = 'NetworkMismatchError';\n this.expected = String(expected);\n this.got = String(got);\n }\n}\n\nexport class ProviderError extends Error {\n readonly code = 'PROVIDER_ERROR' as const;\n\n constructor(message: string) {\n super(`[awarizon/web3] Provider error: ${message}`);\n this.name = 'ProviderError';\n }\n}\n\nexport class ContractNotLoadedError extends Error {\n readonly code = 'CONTRACT_NOT_LOADED' as const;\n\n constructor(address: string) {\n super(`[awarizon/web3] Contract at ${address} is not loaded. Call sdk.contract({ address, abi }) first.`);\n this.name = 'ContractNotLoadedError';\n }\n}\n\nexport class UnsupportedChainError extends Error {\n readonly code = 'UNSUPPORTED_CHAIN' as const;\n readonly chain: string;\n\n constructor(chain: string) {\n super(`[awarizon/web3] Unsupported chain: \"${chain}\". Pass a valid chain name or viem Chain object.`);\n this.name = 'UnsupportedChainError';\n this.chain = chain;\n }\n}\n","import {\n createPublicClient,\n http,\n type Chain,\n type WalletClient,\n type PublicClient,\n type Address,\n type Abi,\n} from 'viem';\nimport { WalletEngine } from '@awarizon/wallet-engine';\nimport { resolveChain } from './chains';\nimport { buildContractInstance } from './contract';\nimport type {\n AwarizonConfig,\n ContractConfig,\n ContractInstance,\n SDKWalletInfo,\n} from './types';\n\n// Re-export errors for convenience so consumers don't need extra imports\nexport {\n WalletNotConnectedError,\n InvalidMnemonicError,\n InvalidPrivateKeyError,\n} from '@awarizon/wallet-engine';\n\nexport {\n ContractExecutionError,\n SimulationError,\n GasEstimationError,\n} from '@awarizon/tx-engine';\n\nexport {\n InvalidABIError,\n} from '@awarizon/abi-engine';\n\nexport {\n NetworkMismatchError,\n ProviderError,\n ContractNotLoadedError,\n UnsupportedChainError,\n} from './errors';\n\n// ─── AwarizonWeb3 ─────────────────────────────────────────────────────────────\n\n/**\n * The primary entry point for the Awarizon Web3 SDK.\n *\n * ```ts\n * const sdk = new AwarizonWeb3({ chain: \"base\" })\n *\n * // Internal wallet\n * const wallet = await sdk.wallet.create()\n *\n * // Load a contract and call it\n * const staking = await sdk.contract({ address: \"0x...\", abi })\n * await staking.stake(100n)\n * const balance = await staking.getBalance(wallet.address)\n *\n * // Listen for events\n * staking.on(\"Staked\", (log) => console.log(log))\n * ```\n */\nexport class AwarizonWeb3 {\n /** The resolved viem Chain */\n readonly chain: Chain;\n\n /** Internal wallet + signer management */\n readonly wallet: WalletEngine;\n\n /** The underlying viem PublicClient used for reads */\n readonly publicClient: PublicClient;\n\n constructor(config: AwarizonConfig) {\n this.chain = resolveChain(config.chain);\n\n this.publicClient = createPublicClient({\n chain: this.chain,\n transport: http(config.rpcUrl),\n });\n\n this.wallet = new WalletEngine({\n chain: this.chain,\n publicClient: this.publicClient,\n rpcUrl: config.rpcUrl,\n });\n\n // Pre-connect external signer if provided at construction time\n if (config.signer) {\n this.wallet.connectExternal(config.signer);\n }\n }\n\n // ─── Wallet API surface ─────────────────────────────────────────────────────\n\n /**\n * Connect an external wallet client (wagmi, WalletConnect, viem, EIP-1193).\n * The connected signer takes priority over any internal wallet.\n *\n * @example\n * sdk.connectWallet(walletClient)\n */\n connectWallet(walletClient: WalletClient): this {\n this.wallet.connectExternal(walletClient);\n return this;\n }\n\n /**\n * Disconnect the externally-connected wallet.\n * Falls back to the internal wallet if one is loaded.\n */\n disconnectWallet(): this {\n this.wallet.disconnectExternal();\n return this;\n }\n\n /**\n * Switch the active chain.\n * Rebuilds the PublicClient and internal WalletClient for the new chain.\n */\n async switchChain(chain: Chain | string): Promise<this> {\n const resolved = resolveChain(chain);\n await this.wallet.switchChain(resolved);\n return this;\n }\n\n /**\n * Returns a summary of the currently active wallet.\n * @throws {WalletNotConnectedError} if no wallet is connected\n */\n getWalletInfo(): SDKWalletInfo {\n return {\n address: this.wallet.address(),\n chain: this.chain,\n isExternal: this.wallet.hasExternalWallet(),\n };\n }\n\n // ─── Contract API ───────────────────────────────────────────────────────────\n\n /**\n * Load a deployed smart contract and return a fully typed, ABI-powered\n * instance. Every function in the ABI is exposed as a direct method.\n *\n * **Read functions** (view / pure) use the PublicClient — no signer needed.\n * **Write functions** (nonpayable / payable) use the active WalletClient.\n *\n * @example\n * const token = await sdk.contract({ address: \"0x...\", abi: ERC20_ABI })\n * const balance = await token.balanceOf(address) // read\n * await token.transfer(to, 100n) // write\n * token.on(\"Transfer\", handler) // events\n */\n async contract<TAbi extends Abi>(config: ContractConfig<TAbi>): Promise<ContractInstance> {\n if (!config.address || !config.abi) {\n throw new Error('[awarizon/web3] sdk.contract() requires both address and abi');\n }\n\n return buildContractInstance(\n config.address,\n config.abi as Abi,\n this.publicClient,\n () => this.wallet.getWalletClient(),\n );\n }\n\n /**\n * Returns the chain ID of the current chain.\n * Useful for runtime network validation.\n */\n get chainId(): number {\n return this.chain.id;\n }\n\n /**\n * Check whether any wallet (internal or external) is connected.\n */\n get isConnected(): boolean {\n return this.wallet.isConnected();\n }\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@awarizon/web3",
3
+ "version": "1.0.0",
4
+ "description": "Core Awarizon Web3 SDK — production-grade EVM blockchain abstraction layer",
5
+ "keywords": ["web3", "ethereum", "evm", "viem", "blockchain", "sdk", "smart-contracts"],
6
+ "license": "MIT",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.mjs",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.js",
14
+ "types": "./dist/index.d.ts"
15
+ }
16
+ },
17
+ "files": ["dist"],
18
+ "scripts": {
19
+ "build": "tsup",
20
+ "dev": "tsup --watch",
21
+ "test": "vitest run",
22
+ "typecheck": "tsc --noEmit",
23
+ "clean": "rimraf dist"
24
+ },
25
+ "dependencies": {
26
+ "@awarizon/abi-engine": "workspace:*",
27
+ "@awarizon/wallet-engine": "workspace:*",
28
+ "@awarizon/tx-engine": "workspace:*",
29
+ "viem": "^2.21.0"
30
+ },
31
+ "devDependencies": {
32
+ "typescript": "^5.5.0",
33
+ "tsup": "^8.2.0",
34
+ "vitest": "^2.0.0",
35
+ "rimraf": "^5.0.0"
36
+ },
37
+ "sideEffects": false
38
+ }