@asentum/sdk 0.1.0 → 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/src/client.ts DELETED
@@ -1,272 +0,0 @@
1
- // Copyright 2026 The AsentumChain Contributors
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- /**
5
- * AsentumClient — read-only interface to an Asentum node's RPC.
6
- *
7
- * Wraps the node's HTTP endpoints in a typed, Promise-based API.
8
- * No private keys, no signing — just reads. For sending transactions,
9
- * use {@link AsentumWallet} which extends the client with a keypair.
10
- *
11
- * Works in Node.js (20+) and browsers — only depends on `fetch`.
12
- */
13
-
14
- export interface ChainInfo {
15
- chainId: string;
16
- height: number;
17
- mempoolSize: number;
18
- latestHeader: BlockHeader;
19
- }
20
-
21
- export interface BlockHeader {
22
- parentHash: string;
23
- stateRoot: string;
24
- transactionsRoot: string;
25
- receiptsRoot: string;
26
- number: string;
27
- timestamp: string;
28
- gasLimit: string;
29
- gasUsed: string;
30
- baseFeePerGas: string;
31
- proposer: string;
32
- }
33
-
34
- export interface Block {
35
- header: BlockHeader;
36
- hash?: string;
37
- transactions: Transaction[];
38
- receipts: Receipt[];
39
- }
40
-
41
- export interface Transaction {
42
- kind: 'transfer' | 'deploy' | 'call';
43
- body: {
44
- chainId: string;
45
- nonce: string;
46
- maxPriorityFeePerGas: string;
47
- maxFeePerGas: string;
48
- gasLimit: string;
49
- to: string;
50
- value: string;
51
- dataSize: number;
52
- };
53
- call?: {
54
- method: string;
55
- args: unknown[];
56
- };
57
- }
58
-
59
- export interface Receipt {
60
- txHash: string;
61
- blockNumber: string;
62
- txIndex: number;
63
- sender: string;
64
- recipient: string;
65
- kind: string;
66
- success: boolean;
67
- gasUsed: string;
68
- events: Array<{ name: string; data: unknown }>;
69
- returnValue?: unknown;
70
- }
71
-
72
- export interface Balance {
73
- address: string;
74
- balance: string;
75
- nonce: string;
76
- }
77
-
78
- export interface ValidatorInfo {
79
- address: string;
80
- stake: string;
81
- bondedAt: string;
82
- pubKeySize: number;
83
- }
84
-
85
- export interface ViewCallResult {
86
- ok: boolean;
87
- reason?: string;
88
- returnValue?: unknown;
89
- gasUsed?: string;
90
- events?: Array<{ name: string; data: unknown }>;
91
- }
92
-
93
- export interface TxResult {
94
- accepted: boolean;
95
- reason?: string;
96
- txHash?: string;
97
- }
98
-
99
- export interface Metadata {
100
- chainId: string;
101
- chainName: string;
102
- chainIdDecimal: string;
103
- currentBlock: string;
104
- nativeCurrency: { name: string; symbol: string; decimals: number };
105
- rpcUrls: string[];
106
- blockExplorerUrls: string[];
107
- faucetUrl: string;
108
- }
109
-
110
- export class AsentumClient {
111
- readonly rpcUrl: string;
112
-
113
- constructor(rpcUrl: string) {
114
- this.rpcUrl = rpcUrl.replace(/\/$/, '');
115
- }
116
-
117
- // ---------------------------------------------------------------------------
118
- // Chain reads
119
- // ---------------------------------------------------------------------------
120
-
121
- /** Get chain info including the latest block header. */
122
- async getChainInfo(): Promise<ChainInfo> {
123
- const raw = await this.get<ChainInfo & { height: string }>('/chain');
124
- return { ...raw, height: Number(BigInt(raw.height)) };
125
- }
126
-
127
- /** Get the current block height. */
128
- async getBlockNumber(): Promise<number> {
129
- const info = await this.getChainInfo();
130
- return info.height;
131
- }
132
-
133
- /** Get the chain ID as a bigint. */
134
- async getChainId(): Promise<bigint> {
135
- const info = await this.getChainInfo();
136
- return BigInt(info.chainId);
137
- }
138
-
139
- /** Get a block by number, including transactions and receipts. */
140
- async getBlock(number: number | bigint): Promise<Block | null> {
141
- try {
142
- return await this.get<Block>(`/block/${number}`);
143
- } catch {
144
- return null;
145
- }
146
- }
147
-
148
- /** Get the balance and nonce for an address. */
149
- async getBalance(address: string): Promise<Balance> {
150
- return this.get<Balance>(`/balance/${address}`);
151
- }
152
-
153
- /** Get the nonce for an address (shorthand for getBalance().nonce). */
154
- async getNonce(address: string): Promise<bigint> {
155
- const bal = await this.getBalance(address);
156
- return BigInt(bal.nonce);
157
- }
158
-
159
- /** Get the receipt for a transaction by hash. */
160
- async getReceipt(txHash: string): Promise<Receipt | null> {
161
- try {
162
- const r = await this.get<Receipt | { error: string; txHash: string }>(`/receipts/${txHash}`);
163
- // The chain returns 200 OK with { error: "receipt not found", txHash }
164
- // when a tx isn't yet mined. Treat that as "not found" so callers
165
- // (notably tx.wait's polling loop) can keep waiting.
166
- if (r && typeof r === 'object' && 'error' in r) return null;
167
- return r as Receipt;
168
- } catch {
169
- return null;
170
- }
171
- }
172
-
173
- /** Get the source code of a deployed contract (hex-encoded). */
174
- async getCode(address: string): Promise<string> {
175
- const res = await this.jsonRpc<string>('eth_getCode', [address, 'latest']);
176
- return res;
177
- }
178
-
179
- /** Get the source code of a deployed contract as a UTF-8 string. */
180
- async getContractSource(address: string): Promise<string | null> {
181
- const hex = await this.getCode(address);
182
- if (!hex || hex === '0x' || hex.length <= 2) return null;
183
- const raw = hex.startsWith('0x') ? hex.slice(2) : hex;
184
- const bytes = new Uint8Array(raw.length / 2);
185
- for (let i = 0; i < bytes.length; i++) {
186
- bytes[i] = parseInt(raw.substr(i * 2, 2), 16);
187
- }
188
- return new TextDecoder().decode(bytes);
189
- }
190
-
191
- /** Call a contract view function (read-only, no transaction). */
192
- async viewCall(contract: string, method: string, args: unknown[] = []): Promise<ViewCallResult> {
193
- return this.post<ViewCallResult>('/view', { contract, method, args });
194
- }
195
-
196
- /** Get the current active validator set. */
197
- async getValidators(): Promise<{ count: number; validators: ValidatorInfo[] }> {
198
- return this.get('/validators');
199
- }
200
-
201
- /** Get the chain metadata (EIP-3085 shape). */
202
- async getMetadata(): Promise<Metadata> {
203
- return this.get<Metadata>('/metadata');
204
- }
205
-
206
- /** Health check. */
207
- async isHealthy(): Promise<boolean> {
208
- try {
209
- const res = await this.get<{ status: string }>('/health');
210
- return res.status === 'ok';
211
- } catch {
212
- return false;
213
- }
214
- }
215
-
216
- /** Readiness check (chain advancing). */
217
- async isReady(): Promise<boolean> {
218
- try {
219
- await fetch(`${this.rpcUrl}/ready`);
220
- return true;
221
- } catch {
222
- return false;
223
- }
224
- }
225
-
226
- /** Request test ASE from the faucet. */
227
- async faucet(to: string, amount: string = '100000000000000000000'): Promise<TxResult> {
228
- return this.post<TxResult>('/dev/faucet', { to, amount });
229
- }
230
-
231
- /** Submit a raw signed transaction (hex-encoded SSZ bytes). */
232
- async submitRawTx(rawTxHex: string): Promise<TxResult> {
233
- return this.post<TxResult>('/tx', { rawTx: rawTxHex });
234
- }
235
-
236
- // ---------------------------------------------------------------------------
237
- // Ethereum JSON-RPC (subset)
238
- // ---------------------------------------------------------------------------
239
-
240
- /** Send a raw JSON-RPC request. */
241
- async jsonRpc<T>(method: string, params: unknown[] = []): Promise<T> {
242
- const res = await fetch(`${this.rpcUrl}/`, {
243
- method: 'POST',
244
- headers: { 'Content-Type': 'application/json' },
245
- body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),
246
- });
247
- if (!res.ok) throw new Error(`JSON-RPC ${method} failed: ${res.status}`);
248
- const body = (await res.json()) as { result?: T; error?: { message: string } };
249
- if (body.error) throw new Error(`JSON-RPC error: ${body.error.message}`);
250
- return body.result as T;
251
- }
252
-
253
- // ---------------------------------------------------------------------------
254
- // Internal HTTP helpers
255
- // ---------------------------------------------------------------------------
256
-
257
- private async get<T>(path: string): Promise<T> {
258
- const res = await fetch(`${this.rpcUrl}${path}`);
259
- if (!res.ok) throw new Error(`GET ${path} failed: ${res.status} ${res.statusText}`);
260
- return (await res.json()) as T;
261
- }
262
-
263
- private async post<T>(path: string, body: unknown): Promise<T> {
264
- const res = await fetch(`${this.rpcUrl}${path}`, {
265
- method: 'POST',
266
- headers: { 'Content-Type': 'application/json' },
267
- body: JSON.stringify(body),
268
- });
269
- if (!res.ok) throw new Error(`POST ${path} failed: ${res.status} ${res.statusText}`);
270
- return (await res.json()) as T;
271
- }
272
- }
package/src/contract.ts DELETED
@@ -1,138 +0,0 @@
1
- // Copyright 2026 The AsentumChain Contributors
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- /**
5
- * AsentumContract — a deployed contract instance that wraps view calls
6
- * and write transactions.
7
- *
8
- * Usage:
9
- *
10
- * // Deploy via a wallet
11
- * const contract = await wallet.deploy(source);
12
- * console.log(contract.address);
13
- *
14
- * // Or wrap an existing deployed contract
15
- * const contract = new AsentumContract(client, '0xabc...');
16
- *
17
- * // Read (free, no signature)
18
- * const name = await contract.view('name');
19
- * const balance = await contract.view('balanceOf', ['0x...']);
20
- *
21
- * // Write (requires a wallet)
22
- * const tx = await contract.send('transfer', ['0x...', '1000']);
23
- * const receipt = await tx.wait();
24
- */
25
-
26
- import { AsentumClient, type Receipt, type ViewCallResult } from './client.js';
27
- import type { AsentumWallet, SentTx } from './wallet.js';
28
-
29
- export class AsentumContract {
30
- readonly client: AsentumClient;
31
- readonly address: string;
32
- /** The deploy tx, if this contract was deployed in this session. */
33
- readonly deployTx?: SentTx;
34
- /** The wallet used to deploy this contract, if any. Used as default signer for send(). */
35
- private wallet?: AsentumWallet;
36
-
37
- constructor(
38
- client: AsentumClient,
39
- address: string,
40
- deployTx?: SentTx,
41
- wallet?: AsentumWallet,
42
- ) {
43
- this.client = client;
44
- this.address = address;
45
- this.deployTx = deployTx;
46
- this.wallet = wallet;
47
- }
48
-
49
- /**
50
- * Call a view function (read-only, free, no transaction).
51
- *
52
- * @param method - The function name to call.
53
- * @param args - Arguments to pass to the function.
54
- * @returns The return value of the function.
55
- */
56
- async view(method: string, args: unknown[] = []): Promise<unknown> {
57
- const result = await this.client.viewCall(this.address, method, args);
58
- if (!result.ok) {
59
- throw new Error(`view call ${method}() failed: ${result.reason || 'unknown'}`);
60
- }
61
- return result.returnValue;
62
- }
63
-
64
- /**
65
- * Call a view function and return the full result including gas + events.
66
- */
67
- async viewFull(method: string, args: unknown[] = []): Promise<ViewCallResult> {
68
- return this.client.viewCall(this.address, method, args);
69
- }
70
-
71
- /**
72
- * Send a state-changing transaction to the contract.
73
- *
74
- * @param method - The function name to call.
75
- * @param args - Arguments to pass.
76
- * @param opts - Optional: value to attach, gas limit, nonce, wallet override.
77
- * @returns A SentTx with `.hash` and `.wait()`.
78
- */
79
- async send(
80
- method: string,
81
- args: unknown[] = [],
82
- opts: {
83
- value?: string | number | bigint;
84
- gasLimit?: bigint;
85
- nonce?: bigint;
86
- wallet?: AsentumWallet;
87
- } = {},
88
- ): Promise<SentTx> {
89
- const signer = opts.wallet ?? this.wallet;
90
- if (!signer) {
91
- throw new Error(
92
- 'no wallet available — pass a wallet in opts or create the contract via wallet.deploy()',
93
- );
94
- }
95
- return signer.sendCall({
96
- to: this.address,
97
- method,
98
- args,
99
- value: opts.value,
100
- gasLimit: opts.gasLimit,
101
- nonce: opts.nonce,
102
- });
103
- }
104
-
105
- /**
106
- * Attach a wallet to this contract for future send() calls.
107
- */
108
- connect(wallet: AsentumWallet): AsentumContract {
109
- return new AsentumContract(this.client, this.address, this.deployTx, wallet);
110
- }
111
-
112
- /**
113
- * Get the source code of this contract as a UTF-8 string.
114
- * Returns null if the address has no deployed code.
115
- */
116
- async getSource(): Promise<string | null> {
117
- return this.client.getContractSource(this.address);
118
- }
119
-
120
- /**
121
- * Get the ASE balance of this contract.
122
- */
123
- async getBalance(): Promise<bigint> {
124
- const bal = await this.client.getBalance(this.address);
125
- return BigInt(bal.balance);
126
- }
127
-
128
- /**
129
- * Wait for the deploy transaction to be confirmed (if this contract
130
- * was deployed in this session). Useful after `wallet.deploy()`.
131
- */
132
- async waitForDeploy(timeoutMs = 15_000): Promise<Receipt> {
133
- if (!this.deployTx) {
134
- throw new Error('this contract was not deployed in this session — no deploy tx to wait for');
135
- }
136
- return this.deployTx.wait(timeoutMs);
137
- }
138
- }
package/src/index.ts DELETED
@@ -1,75 +0,0 @@
1
- // Copyright 2026 The AsentumChain Contributors
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- /**
5
- * @asentum/sdk — TypeScript SDK for building on Asentum.
6
- *
7
- * Three main classes:
8
- *
9
- * - {@link AsentumClient} — read-only interface to the chain
10
- * - {@link AsentumWallet} — keypair + signing + submitting
11
- * - {@link AsentumContract} — deployed contract interaction
12
- *
13
- * Quick start:
14
- *
15
- * ```ts
16
- * import { AsentumClient, AsentumWallet } from '@asentum/sdk';
17
- *
18
- * const client = new AsentumClient('https://testnet.asentum.com');
19
- * const wallet = AsentumWallet.create(client);
20
- *
21
- * // Fund the wallet from the testnet faucet
22
- * await wallet.requestFaucet();
23
- *
24
- * // Check balance
25
- * const balance = await wallet.getBalance();
26
- * console.log('balance:', balance, 'wei');
27
- *
28
- * // Deploy a contract
29
- * const contract = await wallet.deploy(`
30
- * function init() { storage.set('msg', 'hello'); emit('Init', {}); }
31
- * function getMessage() { return storage.get('msg'); }
32
- * function setMessage(m) { storage.set('msg', m); emit('Set', { m }); }
33
- * `);
34
- * console.log('deployed at:', contract.address);
35
- *
36
- * // Initialize the contract
37
- * const initTx = await contract.send('init');
38
- * await initTx.wait();
39
- *
40
- * // Read from the contract (free, no tx)
41
- * const msg = await contract.view('getMessage');
42
- * console.log('message:', msg); // "hello"
43
- *
44
- * // Write to the contract (sends a tx)
45
- * const setTx = await contract.send('setMessage', ['world']);
46
- * await setTx.wait();
47
- *
48
- * const msg2 = await contract.view('getMessage');
49
- * console.log('message:', msg2); // "world"
50
- * ```
51
- */
52
-
53
- export { AsentumClient } from './client.js';
54
- export type {
55
- Balance,
56
- Block,
57
- BlockHeader,
58
- ChainInfo,
59
- Metadata,
60
- Receipt,
61
- Transaction,
62
- TxResult,
63
- ValidatorInfo,
64
- ViewCallResult,
65
- } from './client.js';
66
-
67
- export { AsentumWallet, parseAse, formatAse } from './wallet.js';
68
- export type {
69
- DeployOpts,
70
- SendCallOpts,
71
- SendTransferOpts,
72
- SentTx,
73
- } from './wallet.js';
74
-
75
- export { AsentumContract } from './contract.js';