@asentum/sdk 0.1.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 +201 -0
- package/README.md +202 -0
- package/dist/index.d.ts +307 -0
- package/dist/index.js +444 -0
- package/dist/index.js.map +1 -0
- package/package.json +47 -0
- package/src/client.ts +272 -0
- package/src/contract.ts +138 -0
- package/src/index.ts +75 -0
- package/src/wallet.ts +352 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
var AsentumClient = class {
|
|
3
|
+
rpcUrl;
|
|
4
|
+
constructor(rpcUrl) {
|
|
5
|
+
this.rpcUrl = rpcUrl.replace(/\/$/, "");
|
|
6
|
+
}
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Chain reads
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/** Get chain info including the latest block header. */
|
|
11
|
+
async getChainInfo() {
|
|
12
|
+
const raw = await this.get("/chain");
|
|
13
|
+
return { ...raw, height: Number(BigInt(raw.height)) };
|
|
14
|
+
}
|
|
15
|
+
/** Get the current block height. */
|
|
16
|
+
async getBlockNumber() {
|
|
17
|
+
const info = await this.getChainInfo();
|
|
18
|
+
return info.height;
|
|
19
|
+
}
|
|
20
|
+
/** Get the chain ID as a bigint. */
|
|
21
|
+
async getChainId() {
|
|
22
|
+
const info = await this.getChainInfo();
|
|
23
|
+
return BigInt(info.chainId);
|
|
24
|
+
}
|
|
25
|
+
/** Get a block by number, including transactions and receipts. */
|
|
26
|
+
async getBlock(number) {
|
|
27
|
+
try {
|
|
28
|
+
return await this.get(`/block/${number}`);
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** Get the balance and nonce for an address. */
|
|
34
|
+
async getBalance(address) {
|
|
35
|
+
return this.get(`/balance/${address}`);
|
|
36
|
+
}
|
|
37
|
+
/** Get the nonce for an address (shorthand for getBalance().nonce). */
|
|
38
|
+
async getNonce(address) {
|
|
39
|
+
const bal = await this.getBalance(address);
|
|
40
|
+
return BigInt(bal.nonce);
|
|
41
|
+
}
|
|
42
|
+
/** Get the receipt for a transaction by hash. */
|
|
43
|
+
async getReceipt(txHash) {
|
|
44
|
+
try {
|
|
45
|
+
const r = await this.get(`/receipts/${txHash}`);
|
|
46
|
+
if (r && typeof r === "object" && "error" in r) return null;
|
|
47
|
+
return r;
|
|
48
|
+
} catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** Get the source code of a deployed contract (hex-encoded). */
|
|
53
|
+
async getCode(address) {
|
|
54
|
+
const res = await this.jsonRpc("eth_getCode", [address, "latest"]);
|
|
55
|
+
return res;
|
|
56
|
+
}
|
|
57
|
+
/** Get the source code of a deployed contract as a UTF-8 string. */
|
|
58
|
+
async getContractSource(address) {
|
|
59
|
+
const hex = await this.getCode(address);
|
|
60
|
+
if (!hex || hex === "0x" || hex.length <= 2) return null;
|
|
61
|
+
const raw = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
62
|
+
const bytes = new Uint8Array(raw.length / 2);
|
|
63
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
64
|
+
bytes[i] = parseInt(raw.substr(i * 2, 2), 16);
|
|
65
|
+
}
|
|
66
|
+
return new TextDecoder().decode(bytes);
|
|
67
|
+
}
|
|
68
|
+
/** Call a contract view function (read-only, no transaction). */
|
|
69
|
+
async viewCall(contract, method, args = []) {
|
|
70
|
+
return this.post("/view", { contract, method, args });
|
|
71
|
+
}
|
|
72
|
+
/** Get the current active validator set. */
|
|
73
|
+
async getValidators() {
|
|
74
|
+
return this.get("/validators");
|
|
75
|
+
}
|
|
76
|
+
/** Get the chain metadata (EIP-3085 shape). */
|
|
77
|
+
async getMetadata() {
|
|
78
|
+
return this.get("/metadata");
|
|
79
|
+
}
|
|
80
|
+
/** Health check. */
|
|
81
|
+
async isHealthy() {
|
|
82
|
+
try {
|
|
83
|
+
const res = await this.get("/health");
|
|
84
|
+
return res.status === "ok";
|
|
85
|
+
} catch {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** Readiness check (chain advancing). */
|
|
90
|
+
async isReady() {
|
|
91
|
+
try {
|
|
92
|
+
await fetch(`${this.rpcUrl}/ready`);
|
|
93
|
+
return true;
|
|
94
|
+
} catch {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/** Request test ASE from the faucet. */
|
|
99
|
+
async faucet(to, amount = "100000000000000000000") {
|
|
100
|
+
return this.post("/dev/faucet", { to, amount });
|
|
101
|
+
}
|
|
102
|
+
/** Submit a raw signed transaction (hex-encoded SSZ bytes). */
|
|
103
|
+
async submitRawTx(rawTxHex) {
|
|
104
|
+
return this.post("/tx", { rawTx: rawTxHex });
|
|
105
|
+
}
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
// Ethereum JSON-RPC (subset)
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
/** Send a raw JSON-RPC request. */
|
|
110
|
+
async jsonRpc(method, params = []) {
|
|
111
|
+
const res = await fetch(`${this.rpcUrl}/`, {
|
|
112
|
+
method: "POST",
|
|
113
|
+
headers: { "Content-Type": "application/json" },
|
|
114
|
+
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params })
|
|
115
|
+
});
|
|
116
|
+
if (!res.ok) throw new Error(`JSON-RPC ${method} failed: ${res.status}`);
|
|
117
|
+
const body = await res.json();
|
|
118
|
+
if (body.error) throw new Error(`JSON-RPC error: ${body.error.message}`);
|
|
119
|
+
return body.result;
|
|
120
|
+
}
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
// Internal HTTP helpers
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
async get(path) {
|
|
125
|
+
const res = await fetch(`${this.rpcUrl}${path}`);
|
|
126
|
+
if (!res.ok) throw new Error(`GET ${path} failed: ${res.status} ${res.statusText}`);
|
|
127
|
+
return await res.json();
|
|
128
|
+
}
|
|
129
|
+
async post(path, body) {
|
|
130
|
+
const res = await fetch(`${this.rpcUrl}${path}`, {
|
|
131
|
+
method: "POST",
|
|
132
|
+
headers: { "Content-Type": "application/json" },
|
|
133
|
+
body: JSON.stringify(body)
|
|
134
|
+
});
|
|
135
|
+
if (!res.ok) throw new Error(`POST ${path} failed: ${res.status} ${res.statusText}`);
|
|
136
|
+
return await res.json();
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// src/wallet.ts
|
|
141
|
+
import {
|
|
142
|
+
generateKeypair,
|
|
143
|
+
addressFromPublicKey
|
|
144
|
+
} from "@asentum/crypto";
|
|
145
|
+
import {
|
|
146
|
+
SignedTransactionSchema,
|
|
147
|
+
TransactionBodySchema
|
|
148
|
+
} from "@asentum/types";
|
|
149
|
+
import { blake3, sign } from "@asentum/crypto";
|
|
150
|
+
|
|
151
|
+
// src/contract.ts
|
|
152
|
+
var AsentumContract = class _AsentumContract {
|
|
153
|
+
client;
|
|
154
|
+
address;
|
|
155
|
+
/** The deploy tx, if this contract was deployed in this session. */
|
|
156
|
+
deployTx;
|
|
157
|
+
/** The wallet used to deploy this contract, if any. Used as default signer for send(). */
|
|
158
|
+
wallet;
|
|
159
|
+
constructor(client, address, deployTx, wallet) {
|
|
160
|
+
this.client = client;
|
|
161
|
+
this.address = address;
|
|
162
|
+
this.deployTx = deployTx;
|
|
163
|
+
this.wallet = wallet;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Call a view function (read-only, free, no transaction).
|
|
167
|
+
*
|
|
168
|
+
* @param method - The function name to call.
|
|
169
|
+
* @param args - Arguments to pass to the function.
|
|
170
|
+
* @returns The return value of the function.
|
|
171
|
+
*/
|
|
172
|
+
async view(method, args = []) {
|
|
173
|
+
const result = await this.client.viewCall(this.address, method, args);
|
|
174
|
+
if (!result.ok) {
|
|
175
|
+
throw new Error(`view call ${method}() failed: ${result.reason || "unknown"}`);
|
|
176
|
+
}
|
|
177
|
+
return result.returnValue;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Call a view function and return the full result including gas + events.
|
|
181
|
+
*/
|
|
182
|
+
async viewFull(method, args = []) {
|
|
183
|
+
return this.client.viewCall(this.address, method, args);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Send a state-changing transaction to the contract.
|
|
187
|
+
*
|
|
188
|
+
* @param method - The function name to call.
|
|
189
|
+
* @param args - Arguments to pass.
|
|
190
|
+
* @param opts - Optional: value to attach, gas limit, nonce, wallet override.
|
|
191
|
+
* @returns A SentTx with `.hash` and `.wait()`.
|
|
192
|
+
*/
|
|
193
|
+
async send(method, args = [], opts = {}) {
|
|
194
|
+
const signer = opts.wallet ?? this.wallet;
|
|
195
|
+
if (!signer) {
|
|
196
|
+
throw new Error(
|
|
197
|
+
"no wallet available \u2014 pass a wallet in opts or create the contract via wallet.deploy()"
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
return signer.sendCall({
|
|
201
|
+
to: this.address,
|
|
202
|
+
method,
|
|
203
|
+
args,
|
|
204
|
+
value: opts.value,
|
|
205
|
+
gasLimit: opts.gasLimit,
|
|
206
|
+
nonce: opts.nonce
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Attach a wallet to this contract for future send() calls.
|
|
211
|
+
*/
|
|
212
|
+
connect(wallet) {
|
|
213
|
+
return new _AsentumContract(this.client, this.address, this.deployTx, wallet);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Get the source code of this contract as a UTF-8 string.
|
|
217
|
+
* Returns null if the address has no deployed code.
|
|
218
|
+
*/
|
|
219
|
+
async getSource() {
|
|
220
|
+
return this.client.getContractSource(this.address);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Get the ASE balance of this contract.
|
|
224
|
+
*/
|
|
225
|
+
async getBalance() {
|
|
226
|
+
const bal = await this.client.getBalance(this.address);
|
|
227
|
+
return BigInt(bal.balance);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Wait for the deploy transaction to be confirmed (if this contract
|
|
231
|
+
* was deployed in this session). Useful after `wallet.deploy()`.
|
|
232
|
+
*/
|
|
233
|
+
async waitForDeploy(timeoutMs = 15e3) {
|
|
234
|
+
if (!this.deployTx) {
|
|
235
|
+
throw new Error("this contract was not deployed in this session \u2014 no deploy tx to wait for");
|
|
236
|
+
}
|
|
237
|
+
return this.deployTx.wait(timeoutMs);
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
// src/wallet.ts
|
|
242
|
+
function bytesToHex(bytes) {
|
|
243
|
+
let hex = "0x";
|
|
244
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
245
|
+
hex += (bytes[i] ?? 0).toString(16).padStart(2, "0");
|
|
246
|
+
}
|
|
247
|
+
return hex;
|
|
248
|
+
}
|
|
249
|
+
function hexToBytes(hex) {
|
|
250
|
+
let h = hex.startsWith("0x") || hex.startsWith("0X") ? hex.slice(2) : hex;
|
|
251
|
+
if (h.length % 2 !== 0) h = "0" + h;
|
|
252
|
+
const out = new Uint8Array(h.length / 2);
|
|
253
|
+
for (let i = 0; i < out.length; i++) {
|
|
254
|
+
out[i] = parseInt(h.slice(i * 2, i * 2 + 2), 16);
|
|
255
|
+
}
|
|
256
|
+
return out;
|
|
257
|
+
}
|
|
258
|
+
function hexToAddress20(hex) {
|
|
259
|
+
const bytes = hexToBytes(hex);
|
|
260
|
+
if (bytes.length !== 20) throw new Error(`expected 20-byte address, got ${bytes.length}`);
|
|
261
|
+
return bytes;
|
|
262
|
+
}
|
|
263
|
+
function parseAse(amount) {
|
|
264
|
+
if (typeof amount === "bigint") return amount;
|
|
265
|
+
if (typeof amount === "number") return BigInt(Math.floor(amount * 1e18));
|
|
266
|
+
const s = amount.trim();
|
|
267
|
+
if (/^\d+$/.test(s)) {
|
|
268
|
+
if (s.length > 18) return BigInt(s);
|
|
269
|
+
return BigInt(s) * 1000000000000000000n;
|
|
270
|
+
}
|
|
271
|
+
if (/^\d+\.\d{1,18}$/.test(s)) {
|
|
272
|
+
const [whole, frac = ""] = s.split(".");
|
|
273
|
+
const padded = frac.padEnd(18, "0").slice(0, 18);
|
|
274
|
+
return BigInt(whole + padded);
|
|
275
|
+
}
|
|
276
|
+
throw new Error(`invalid amount: "${amount}" \u2014 use "1", "1.5", or a wei integer`);
|
|
277
|
+
}
|
|
278
|
+
function formatAse(wei) {
|
|
279
|
+
const w = typeof wei === "bigint" ? wei : BigInt(wei);
|
|
280
|
+
const whole = w / 1000000000000000000n;
|
|
281
|
+
const frac = w % 1000000000000000000n;
|
|
282
|
+
if (frac === 0n) return whole.toString();
|
|
283
|
+
const fracStr = frac.toString().padStart(18, "0").replace(/0+$/, "");
|
|
284
|
+
return `${whole}.${fracStr}`;
|
|
285
|
+
}
|
|
286
|
+
var AsentumWallet = class _AsentumWallet {
|
|
287
|
+
client;
|
|
288
|
+
keypair;
|
|
289
|
+
address;
|
|
290
|
+
constructor(client, keypair) {
|
|
291
|
+
this.client = client;
|
|
292
|
+
this.keypair = keypair;
|
|
293
|
+
this.address = addressFromPublicKey(keypair.publicKey);
|
|
294
|
+
}
|
|
295
|
+
/** Create a wallet with a random Dilithium3 keypair. */
|
|
296
|
+
static create(client) {
|
|
297
|
+
const seed = new Uint8Array(32);
|
|
298
|
+
crypto.getRandomValues(seed);
|
|
299
|
+
const keypair = generateKeypair(seed);
|
|
300
|
+
return new _AsentumWallet(client, keypair);
|
|
301
|
+
}
|
|
302
|
+
/** Create a wallet from a 32-byte seed. */
|
|
303
|
+
static fromSeed(client, seed) {
|
|
304
|
+
if (seed.length < 32) throw new Error("seed must be at least 32 bytes");
|
|
305
|
+
const keypair = generateKeypair(seed.slice(0, 32));
|
|
306
|
+
return new _AsentumWallet(client, keypair);
|
|
307
|
+
}
|
|
308
|
+
/** Create a wallet from a hex-encoded secret key. */
|
|
309
|
+
static fromSecretKey(client, secretKeyHex, publicKeyHex) {
|
|
310
|
+
return new _AsentumWallet(client, {
|
|
311
|
+
secretKey: hexToBytes(secretKeyHex),
|
|
312
|
+
publicKey: hexToBytes(publicKeyHex)
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
/** Get the secret key as a hex string (for export/backup). */
|
|
316
|
+
get secretKeyHex() {
|
|
317
|
+
return bytesToHex(this.keypair.secretKey);
|
|
318
|
+
}
|
|
319
|
+
/** Get the public key as a hex string. */
|
|
320
|
+
get publicKeyHex() {
|
|
321
|
+
return bytesToHex(this.keypair.publicKey);
|
|
322
|
+
}
|
|
323
|
+
/** Get the current balance in wei. */
|
|
324
|
+
async getBalance() {
|
|
325
|
+
const bal = await this.client.getBalance(this.address);
|
|
326
|
+
return BigInt(bal.balance);
|
|
327
|
+
}
|
|
328
|
+
/** Get the current nonce. */
|
|
329
|
+
async getNonce() {
|
|
330
|
+
return this.client.getNonce(this.address);
|
|
331
|
+
}
|
|
332
|
+
/** Request test ASE from the faucet. */
|
|
333
|
+
async requestFaucet(amount = "100000000000000000000") {
|
|
334
|
+
return this.client.faucet(this.address, amount);
|
|
335
|
+
}
|
|
336
|
+
// ---------------------------------------------------------------------------
|
|
337
|
+
// Sending transactions
|
|
338
|
+
// ---------------------------------------------------------------------------
|
|
339
|
+
/** Send ASE to another address. */
|
|
340
|
+
async sendTransfer(opts) {
|
|
341
|
+
const chainId = await this.client.getChainId();
|
|
342
|
+
const nonce = opts.nonce ?? await this.getNonce();
|
|
343
|
+
const value = parseAse(opts.amount);
|
|
344
|
+
const body = {
|
|
345
|
+
chainId,
|
|
346
|
+
nonce,
|
|
347
|
+
maxPriorityFeePerGas: 0n,
|
|
348
|
+
maxFeePerGas: 1n,
|
|
349
|
+
gasLimit: opts.gasLimit ?? 21000n,
|
|
350
|
+
to: hexToAddress20(opts.to),
|
|
351
|
+
value,
|
|
352
|
+
data: new Uint8Array(0)
|
|
353
|
+
};
|
|
354
|
+
return this.signAndSubmit(body);
|
|
355
|
+
}
|
|
356
|
+
/** Call a method on a deployed contract (state-changing). */
|
|
357
|
+
async sendCall(opts) {
|
|
358
|
+
const chainId = await this.client.getChainId();
|
|
359
|
+
const nonce = opts.nonce ?? await this.getNonce();
|
|
360
|
+
const data = new TextEncoder().encode(
|
|
361
|
+
JSON.stringify({ method: opts.method, args: opts.args ?? [] })
|
|
362
|
+
);
|
|
363
|
+
const body = {
|
|
364
|
+
chainId,
|
|
365
|
+
nonce,
|
|
366
|
+
maxPriorityFeePerGas: 0n,
|
|
367
|
+
maxFeePerGas: 1n,
|
|
368
|
+
gasLimit: opts.gasLimit ?? 2000000n,
|
|
369
|
+
to: hexToAddress20(opts.to),
|
|
370
|
+
value: opts.value ? parseAse(opts.value) : 0n,
|
|
371
|
+
data
|
|
372
|
+
};
|
|
373
|
+
return this.signAndSubmit(body);
|
|
374
|
+
}
|
|
375
|
+
/** Deploy a new smart contract. Returns an AsentumContract instance. */
|
|
376
|
+
async deploy(sourceOrOpts) {
|
|
377
|
+
const opts = typeof sourceOrOpts === "string" ? { source: sourceOrOpts } : sourceOrOpts;
|
|
378
|
+
const chainId = await this.client.getChainId();
|
|
379
|
+
const nonce = opts.nonce ?? await this.getNonce();
|
|
380
|
+
const data = new TextEncoder().encode(opts.source);
|
|
381
|
+
const gasLimit = opts.gasLimit ?? BigInt(Math.max(2e6, 1e3 * opts.source.length));
|
|
382
|
+
const body = {
|
|
383
|
+
chainId,
|
|
384
|
+
nonce,
|
|
385
|
+
maxPriorityFeePerGas: 0n,
|
|
386
|
+
maxFeePerGas: 1n,
|
|
387
|
+
gasLimit,
|
|
388
|
+
to: new Uint8Array(20),
|
|
389
|
+
// zero address = deploy
|
|
390
|
+
value: opts.value ? parseAse(opts.value) : 0n,
|
|
391
|
+
data
|
|
392
|
+
};
|
|
393
|
+
const sentTx = await this.signAndSubmit(body);
|
|
394
|
+
const senderBytes = hexToAddress20(this.address);
|
|
395
|
+
const nonceBytes = new Uint8Array(8);
|
|
396
|
+
new DataView(nonceBytes.buffer).setBigUint64(0, nonce, true);
|
|
397
|
+
const combined = new Uint8Array(20 + 8);
|
|
398
|
+
combined.set(senderBytes);
|
|
399
|
+
combined.set(nonceBytes, 20);
|
|
400
|
+
const hash = blake3(combined);
|
|
401
|
+
const contractAddress = bytesToHex(hash.slice(0, 20));
|
|
402
|
+
return new AsentumContract(this.client, contractAddress, sentTx, this);
|
|
403
|
+
}
|
|
404
|
+
// ---------------------------------------------------------------------------
|
|
405
|
+
// Internal: sign + submit
|
|
406
|
+
// ---------------------------------------------------------------------------
|
|
407
|
+
async signAndSubmit(body) {
|
|
408
|
+
const bodyBytes = TransactionBodySchema.serialize(body);
|
|
409
|
+
const digest = blake3(bodyBytes);
|
|
410
|
+
const signature = sign(digest, this.keypair.secretKey);
|
|
411
|
+
const signedTx = {
|
|
412
|
+
body,
|
|
413
|
+
publicKey: this.keypair.publicKey,
|
|
414
|
+
signature
|
|
415
|
+
};
|
|
416
|
+
const rawTxHex = bytesToHex(SignedTransactionSchema.serialize(signedTx));
|
|
417
|
+
const result = await this.client.submitRawTx(rawTxHex);
|
|
418
|
+
if (!result.accepted) {
|
|
419
|
+
throw new Error(`transaction rejected: ${result.reason || "unknown reason"}`);
|
|
420
|
+
}
|
|
421
|
+
const txHash = result.txHash ?? "(unknown)";
|
|
422
|
+
const client = this.client;
|
|
423
|
+
return {
|
|
424
|
+
hash: txHash,
|
|
425
|
+
async wait(timeoutMs = 15e3) {
|
|
426
|
+
const start = Date.now();
|
|
427
|
+
while (Date.now() - start < timeoutMs) {
|
|
428
|
+
const receipt = await client.getReceipt(txHash);
|
|
429
|
+
if (receipt) return receipt;
|
|
430
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
431
|
+
}
|
|
432
|
+
throw new Error(`transaction ${txHash} not confirmed within ${timeoutMs}ms`);
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
export {
|
|
438
|
+
AsentumClient,
|
|
439
|
+
AsentumContract,
|
|
440
|
+
AsentumWallet,
|
|
441
|
+
formatAse,
|
|
442
|
+
parseAse
|
|
443
|
+
};
|
|
444
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/wallet.ts","../src/contract.ts"],"sourcesContent":["// Copyright 2026 The AsentumChain Contributors\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * AsentumClient — read-only interface to an Asentum node's RPC.\n *\n * Wraps the node's HTTP endpoints in a typed, Promise-based API.\n * No private keys, no signing — just reads. For sending transactions,\n * use {@link AsentumWallet} which extends the client with a keypair.\n *\n * Works in Node.js (20+) and browsers — only depends on `fetch`.\n */\n\nexport interface ChainInfo {\n chainId: string;\n height: number;\n mempoolSize: number;\n latestHeader: BlockHeader;\n}\n\nexport interface BlockHeader {\n parentHash: string;\n stateRoot: string;\n transactionsRoot: string;\n receiptsRoot: string;\n number: string;\n timestamp: string;\n gasLimit: string;\n gasUsed: string;\n baseFeePerGas: string;\n proposer: string;\n}\n\nexport interface Block {\n header: BlockHeader;\n hash?: string;\n transactions: Transaction[];\n receipts: Receipt[];\n}\n\nexport interface Transaction {\n kind: 'transfer' | 'deploy' | 'call';\n body: {\n chainId: string;\n nonce: string;\n maxPriorityFeePerGas: string;\n maxFeePerGas: string;\n gasLimit: string;\n to: string;\n value: string;\n dataSize: number;\n };\n call?: {\n method: string;\n args: unknown[];\n };\n}\n\nexport interface Receipt {\n txHash: string;\n blockNumber: string;\n txIndex: number;\n sender: string;\n recipient: string;\n kind: string;\n success: boolean;\n gasUsed: string;\n events: Array<{ name: string; data: unknown }>;\n returnValue?: unknown;\n}\n\nexport interface Balance {\n address: string;\n balance: string;\n nonce: string;\n}\n\nexport interface ValidatorInfo {\n address: string;\n stake: string;\n bondedAt: string;\n pubKeySize: number;\n}\n\nexport interface ViewCallResult {\n ok: boolean;\n reason?: string;\n returnValue?: unknown;\n gasUsed?: string;\n events?: Array<{ name: string; data: unknown }>;\n}\n\nexport interface TxResult {\n accepted: boolean;\n reason?: string;\n txHash?: string;\n}\n\nexport interface Metadata {\n chainId: string;\n chainName: string;\n chainIdDecimal: string;\n currentBlock: string;\n nativeCurrency: { name: string; symbol: string; decimals: number };\n rpcUrls: string[];\n blockExplorerUrls: string[];\n faucetUrl: string;\n}\n\nexport class AsentumClient {\n readonly rpcUrl: string;\n\n constructor(rpcUrl: string) {\n this.rpcUrl = rpcUrl.replace(/\\/$/, '');\n }\n\n // ---------------------------------------------------------------------------\n // Chain reads\n // ---------------------------------------------------------------------------\n\n /** Get chain info including the latest block header. */\n async getChainInfo(): Promise<ChainInfo> {\n const raw = await this.get<ChainInfo & { height: string }>('/chain');\n return { ...raw, height: Number(BigInt(raw.height)) };\n }\n\n /** Get the current block height. */\n async getBlockNumber(): Promise<number> {\n const info = await this.getChainInfo();\n return info.height;\n }\n\n /** Get the chain ID as a bigint. */\n async getChainId(): Promise<bigint> {\n const info = await this.getChainInfo();\n return BigInt(info.chainId);\n }\n\n /** Get a block by number, including transactions and receipts. */\n async getBlock(number: number | bigint): Promise<Block | null> {\n try {\n return await this.get<Block>(`/block/${number}`);\n } catch {\n return null;\n }\n }\n\n /** Get the balance and nonce for an address. */\n async getBalance(address: string): Promise<Balance> {\n return this.get<Balance>(`/balance/${address}`);\n }\n\n /** Get the nonce for an address (shorthand for getBalance().nonce). */\n async getNonce(address: string): Promise<bigint> {\n const bal = await this.getBalance(address);\n return BigInt(bal.nonce);\n }\n\n /** Get the receipt for a transaction by hash. */\n async getReceipt(txHash: string): Promise<Receipt | null> {\n try {\n const r = await this.get<Receipt | { error: string; txHash: string }>(`/receipts/${txHash}`);\n // The chain returns 200 OK with { error: \"receipt not found\", txHash }\n // when a tx isn't yet mined. Treat that as \"not found\" so callers\n // (notably tx.wait's polling loop) can keep waiting.\n if (r && typeof r === 'object' && 'error' in r) return null;\n return r as Receipt;\n } catch {\n return null;\n }\n }\n\n /** Get the source code of a deployed contract (hex-encoded). */\n async getCode(address: string): Promise<string> {\n const res = await this.jsonRpc<string>('eth_getCode', [address, 'latest']);\n return res;\n }\n\n /** Get the source code of a deployed contract as a UTF-8 string. */\n async getContractSource(address: string): Promise<string | null> {\n const hex = await this.getCode(address);\n if (!hex || hex === '0x' || hex.length <= 2) return null;\n const raw = hex.startsWith('0x') ? hex.slice(2) : hex;\n const bytes = new Uint8Array(raw.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(raw.substr(i * 2, 2), 16);\n }\n return new TextDecoder().decode(bytes);\n }\n\n /** Call a contract view function (read-only, no transaction). */\n async viewCall(contract: string, method: string, args: unknown[] = []): Promise<ViewCallResult> {\n return this.post<ViewCallResult>('/view', { contract, method, args });\n }\n\n /** Get the current active validator set. */\n async getValidators(): Promise<{ count: number; validators: ValidatorInfo[] }> {\n return this.get('/validators');\n }\n\n /** Get the chain metadata (EIP-3085 shape). */\n async getMetadata(): Promise<Metadata> {\n return this.get<Metadata>('/metadata');\n }\n\n /** Health check. */\n async isHealthy(): Promise<boolean> {\n try {\n const res = await this.get<{ status: string }>('/health');\n return res.status === 'ok';\n } catch {\n return false;\n }\n }\n\n /** Readiness check (chain advancing). */\n async isReady(): Promise<boolean> {\n try {\n await fetch(`${this.rpcUrl}/ready`);\n return true;\n } catch {\n return false;\n }\n }\n\n /** Request test ASE from the faucet. */\n async faucet(to: string, amount: string = '100000000000000000000'): Promise<TxResult> {\n return this.post<TxResult>('/dev/faucet', { to, amount });\n }\n\n /** Submit a raw signed transaction (hex-encoded SSZ bytes). */\n async submitRawTx(rawTxHex: string): Promise<TxResult> {\n return this.post<TxResult>('/tx', { rawTx: rawTxHex });\n }\n\n // ---------------------------------------------------------------------------\n // Ethereum JSON-RPC (subset)\n // ---------------------------------------------------------------------------\n\n /** Send a raw JSON-RPC request. */\n async jsonRpc<T>(method: string, params: unknown[] = []): Promise<T> {\n const res = await fetch(`${this.rpcUrl}/`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),\n });\n if (!res.ok) throw new Error(`JSON-RPC ${method} failed: ${res.status}`);\n const body = (await res.json()) as { result?: T; error?: { message: string } };\n if (body.error) throw new Error(`JSON-RPC error: ${body.error.message}`);\n return body.result as T;\n }\n\n // ---------------------------------------------------------------------------\n // Internal HTTP helpers\n // ---------------------------------------------------------------------------\n\n private async get<T>(path: string): Promise<T> {\n const res = await fetch(`${this.rpcUrl}${path}`);\n if (!res.ok) throw new Error(`GET ${path} failed: ${res.status} ${res.statusText}`);\n return (await res.json()) as T;\n }\n\n private async post<T>(path: string, body: unknown): Promise<T> {\n const res = await fetch(`${this.rpcUrl}${path}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n if (!res.ok) throw new Error(`POST ${path} failed: ${res.status} ${res.statusText}`);\n return (await res.json()) as T;\n }\n}\n","// Copyright 2026 The AsentumChain Contributors\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * AsentumWallet — a keypair-backed client that can sign and submit\n * transactions. Extends AsentumClient with signing capabilities.\n *\n * Usage:\n *\n * // Create a random wallet\n * const wallet = AsentumWallet.create(client);\n *\n * // Or from an existing private key (hex)\n * const wallet = AsentumWallet.fromSecretKey(client, '0x...');\n *\n * // Or from a 32-byte seed\n * const wallet = AsentumWallet.fromSeed(client, seed);\n *\n * // Send ASE\n * const tx = await wallet.sendTransfer({ to: '0x...', amount: '1.5' });\n *\n * // Deploy a contract\n * const contract = await wallet.deploy('function init() { ... }');\n *\n * // Call a contract method (write)\n * const tx2 = await wallet.sendCall({\n * to: contract.address,\n * method: 'transfer',\n * args: ['0xbob...', '100'],\n * });\n */\n\nimport {\n generateKeypair,\n addressFromPublicKey,\n type Dilithium3Keypair,\n} from '@asentum/crypto';\nimport {\n SignedTransactionSchema,\n TransactionBodySchema,\n} from '@asentum/types';\nimport { blake3, sign } from '@asentum/crypto';\nimport { AsentumClient, type TxResult } from './client.js';\nimport { AsentumContract } from './contract.js';\n\n// ---------------------------------------------------------------------------\n// Hex helpers\n// ---------------------------------------------------------------------------\n\nfunction bytesToHex(bytes: Uint8Array): string {\n let hex = '0x';\n for (let i = 0; i < bytes.length; i++) {\n hex += (bytes[i] ?? 0).toString(16).padStart(2, '0');\n }\n return hex;\n}\n\nfunction hexToBytes(hex: string): Uint8Array {\n let h = hex.startsWith('0x') || hex.startsWith('0X') ? hex.slice(2) : hex;\n if (h.length % 2 !== 0) h = '0' + h;\n const out = new Uint8Array(h.length / 2);\n for (let i = 0; i < out.length; i++) {\n out[i] = parseInt(h.slice(i * 2, i * 2 + 2), 16);\n }\n return out;\n}\n\nfunction hexToAddress20(hex: string): Uint8Array {\n const bytes = hexToBytes(hex);\n if (bytes.length !== 20) throw new Error(`expected 20-byte address, got ${bytes.length}`);\n return bytes;\n}\n\n// ---------------------------------------------------------------------------\n// Amount parsing\n// ---------------------------------------------------------------------------\n\n/**\n * Parse an ASE amount string into wei (bigint).\n * Accepts: \"1\", \"1.5\", \"0.001\", or a raw wei integer string.\n */\nexport function parseAse(amount: string | number | bigint): bigint {\n if (typeof amount === 'bigint') return amount;\n if (typeof amount === 'number') return BigInt(Math.floor(amount * 1e18));\n const s = amount.trim();\n if (/^\\d+$/.test(s)) {\n // If it's a very large integer, treat as wei. Otherwise ASE.\n if (s.length > 18) return BigInt(s); // likely wei\n return BigInt(s) * 1000000000000000000n; // ASE → wei\n }\n if (/^\\d+\\.\\d{1,18}$/.test(s)) {\n const [whole, frac = ''] = s.split('.');\n const padded = frac.padEnd(18, '0').slice(0, 18);\n return BigInt(whole + padded);\n }\n throw new Error(`invalid amount: \"${amount}\" — use \"1\", \"1.5\", or a wei integer`);\n}\n\n/**\n * Format a wei bigint as a human-readable ASE string.\n */\nexport function formatAse(wei: bigint | string): string {\n const w = typeof wei === 'bigint' ? wei : BigInt(wei);\n const whole = w / 1000000000000000000n;\n const frac = w % 1000000000000000000n;\n if (frac === 0n) return whole.toString();\n const fracStr = frac.toString().padStart(18, '0').replace(/0+$/, '');\n return `${whole}.${fracStr}`;\n}\n\n// ---------------------------------------------------------------------------\n// Transaction building\n// ---------------------------------------------------------------------------\n\nexport interface SendTransferOpts {\n /** Recipient address (0x-prefixed, 40 hex chars). */\n to: string;\n /** Amount in ASE (e.g. \"1.5\") or wei (bigint). */\n amount: string | number | bigint;\n /** Override the gas limit. Default: 21,000. */\n gasLimit?: bigint;\n /** Override the nonce. Default: auto-fetched from the chain. */\n nonce?: bigint;\n}\n\nexport interface SendCallOpts {\n /** Contract address (0x-prefixed, 40 hex chars). */\n to: string;\n /** Method name to call on the contract. */\n method: string;\n /** Method arguments (passed as JSON to the contract). */\n args?: unknown[];\n /** ASE to attach to the call (default: 0). */\n value?: string | number | bigint;\n /** Override the gas limit. Default: 2,000,000. */\n gasLimit?: bigint;\n /** Override the nonce. Default: auto-fetched. */\n nonce?: bigint;\n}\n\nexport interface DeployOpts {\n /** The JavaScript source code of the contract. */\n source: string;\n /** ASE to attach to the deploy (default: 0). */\n value?: string | number | bigint;\n /** Override the gas limit. Default: based on source length. */\n gasLimit?: bigint;\n /** Override the nonce. Default: auto-fetched. */\n nonce?: bigint;\n}\n\nexport interface SentTx {\n /** The transaction hash (0x-prefixed). */\n hash: string;\n /** Wait for the transaction to be included in a block. */\n wait(timeoutMs?: number): Promise<import('./client.js').Receipt>;\n}\n\n// ---------------------------------------------------------------------------\n// AsentumWallet\n// ---------------------------------------------------------------------------\n\nexport class AsentumWallet {\n readonly client: AsentumClient;\n readonly keypair: Dilithium3Keypair;\n readonly address: string;\n\n private constructor(client: AsentumClient, keypair: Dilithium3Keypair) {\n this.client = client;\n this.keypair = keypair;\n this.address = addressFromPublicKey(keypair.publicKey);\n }\n\n /** Create a wallet with a random Dilithium3 keypair. */\n static create(client: AsentumClient): AsentumWallet {\n const seed = new Uint8Array(32);\n crypto.getRandomValues(seed);\n const keypair = generateKeypair(seed);\n return new AsentumWallet(client, keypair);\n }\n\n /** Create a wallet from a 32-byte seed. */\n static fromSeed(client: AsentumClient, seed: Uint8Array): AsentumWallet {\n if (seed.length < 32) throw new Error('seed must be at least 32 bytes');\n const keypair = generateKeypair(seed.slice(0, 32));\n return new AsentumWallet(client, keypair);\n }\n\n /** Create a wallet from a hex-encoded secret key. */\n static fromSecretKey(client: AsentumClient, secretKeyHex: string, publicKeyHex: string): AsentumWallet {\n return new AsentumWallet(client, {\n secretKey: hexToBytes(secretKeyHex),\n publicKey: hexToBytes(publicKeyHex),\n });\n }\n\n /** Get the secret key as a hex string (for export/backup). */\n get secretKeyHex(): string {\n return bytesToHex(this.keypair.secretKey);\n }\n\n /** Get the public key as a hex string. */\n get publicKeyHex(): string {\n return bytesToHex(this.keypair.publicKey);\n }\n\n /** Get the current balance in wei. */\n async getBalance(): Promise<bigint> {\n const bal = await this.client.getBalance(this.address);\n return BigInt(bal.balance);\n }\n\n /** Get the current nonce. */\n async getNonce(): Promise<bigint> {\n return this.client.getNonce(this.address);\n }\n\n /** Request test ASE from the faucet. */\n async requestFaucet(amount: string = '100000000000000000000'): Promise<TxResult> {\n return this.client.faucet(this.address, amount);\n }\n\n // ---------------------------------------------------------------------------\n // Sending transactions\n // ---------------------------------------------------------------------------\n\n /** Send ASE to another address. */\n async sendTransfer(opts: SendTransferOpts): Promise<SentTx> {\n const chainId = await this.client.getChainId();\n const nonce = opts.nonce ?? await this.getNonce();\n const value = parseAse(opts.amount);\n\n const body = {\n chainId,\n nonce,\n maxPriorityFeePerGas: 0n,\n maxFeePerGas: 1n,\n gasLimit: opts.gasLimit ?? 21_000n,\n to: hexToAddress20(opts.to),\n value,\n data: new Uint8Array(0),\n };\n\n return this.signAndSubmit(body);\n }\n\n /** Call a method on a deployed contract (state-changing). */\n async sendCall(opts: SendCallOpts): Promise<SentTx> {\n const chainId = await this.client.getChainId();\n const nonce = opts.nonce ?? await this.getNonce();\n const data = new TextEncoder().encode(\n JSON.stringify({ method: opts.method, args: opts.args ?? [] }),\n );\n\n const body = {\n chainId,\n nonce,\n maxPriorityFeePerGas: 0n,\n maxFeePerGas: 1n,\n gasLimit: opts.gasLimit ?? 2_000_000n,\n to: hexToAddress20(opts.to),\n value: opts.value ? parseAse(opts.value) : 0n,\n data,\n };\n\n return this.signAndSubmit(body);\n }\n\n /** Deploy a new smart contract. Returns an AsentumContract instance. */\n async deploy(sourceOrOpts: string | DeployOpts): Promise<AsentumContract> {\n const opts: DeployOpts = typeof sourceOrOpts === 'string'\n ? { source: sourceOrOpts }\n : sourceOrOpts;\n\n const chainId = await this.client.getChainId();\n const nonce = opts.nonce ?? await this.getNonce();\n const data = new TextEncoder().encode(opts.source);\n const gasLimit = opts.gasLimit ?? BigInt(Math.max(2_000_000, 1000 * opts.source.length));\n\n const body = {\n chainId,\n nonce,\n maxPriorityFeePerGas: 0n,\n maxFeePerGas: 1n,\n gasLimit,\n to: new Uint8Array(20), // zero address = deploy\n value: opts.value ? parseAse(opts.value) : 0n,\n data,\n };\n\n const sentTx = await this.signAndSubmit(body);\n\n // Derive the contract address: blake3(sender || nonce), take first 20 bytes.\n const senderBytes = hexToAddress20(this.address);\n const nonceBytes = new Uint8Array(8);\n new DataView(nonceBytes.buffer).setBigUint64(0, nonce, true);\n const combined = new Uint8Array(20 + 8);\n combined.set(senderBytes);\n combined.set(nonceBytes, 20);\n const hash = blake3(combined);\n const contractAddress = bytesToHex(hash.slice(0, 20));\n\n return new AsentumContract(this.client, contractAddress, sentTx, this);\n }\n\n // ---------------------------------------------------------------------------\n // Internal: sign + submit\n // ---------------------------------------------------------------------------\n\n private async signAndSubmit(body: {\n chainId: bigint;\n nonce: bigint;\n maxPriorityFeePerGas: bigint;\n maxFeePerGas: bigint;\n gasLimit: bigint;\n to: Uint8Array;\n value: bigint;\n data: Uint8Array;\n }): Promise<SentTx> {\n // Serialize → hash → sign → encode → submit\n const bodyBytes = TransactionBodySchema.serialize(body);\n const digest = blake3(bodyBytes);\n const signature = sign(digest, this.keypair.secretKey);\n const signedTx = {\n body,\n publicKey: this.keypair.publicKey,\n signature,\n };\n const rawTxHex = bytesToHex(SignedTransactionSchema.serialize(signedTx));\n const result = await this.client.submitRawTx(rawTxHex);\n\n if (!result.accepted) {\n throw new Error(`transaction rejected: ${result.reason || 'unknown reason'}`);\n }\n\n const txHash = result.txHash ?? '(unknown)';\n const client = this.client;\n\n return {\n hash: txHash,\n async wait(timeoutMs = 15_000): Promise<import('./client.js').Receipt> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n const receipt = await client.getReceipt(txHash);\n if (receipt) return receipt;\n await new Promise((r) => setTimeout(r, 1000));\n }\n throw new Error(`transaction ${txHash} not confirmed within ${timeoutMs}ms`);\n },\n };\n }\n}\n","// Copyright 2026 The AsentumChain Contributors\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * AsentumContract — a deployed contract instance that wraps view calls\n * and write transactions.\n *\n * Usage:\n *\n * // Deploy via a wallet\n * const contract = await wallet.deploy(source);\n * console.log(contract.address);\n *\n * // Or wrap an existing deployed contract\n * const contract = new AsentumContract(client, '0xabc...');\n *\n * // Read (free, no signature)\n * const name = await contract.view('name');\n * const balance = await contract.view('balanceOf', ['0x...']);\n *\n * // Write (requires a wallet)\n * const tx = await contract.send('transfer', ['0x...', '1000']);\n * const receipt = await tx.wait();\n */\n\nimport { AsentumClient, type Receipt, type ViewCallResult } from './client.js';\nimport type { AsentumWallet, SentTx } from './wallet.js';\n\nexport class AsentumContract {\n readonly client: AsentumClient;\n readonly address: string;\n /** The deploy tx, if this contract was deployed in this session. */\n readonly deployTx?: SentTx;\n /** The wallet used to deploy this contract, if any. Used as default signer for send(). */\n private wallet?: AsentumWallet;\n\n constructor(\n client: AsentumClient,\n address: string,\n deployTx?: SentTx,\n wallet?: AsentumWallet,\n ) {\n this.client = client;\n this.address = address;\n this.deployTx = deployTx;\n this.wallet = wallet;\n }\n\n /**\n * Call a view function (read-only, free, no transaction).\n *\n * @param method - The function name to call.\n * @param args - Arguments to pass to the function.\n * @returns The return value of the function.\n */\n async view(method: string, args: unknown[] = []): Promise<unknown> {\n const result = await this.client.viewCall(this.address, method, args);\n if (!result.ok) {\n throw new Error(`view call ${method}() failed: ${result.reason || 'unknown'}`);\n }\n return result.returnValue;\n }\n\n /**\n * Call a view function and return the full result including gas + events.\n */\n async viewFull(method: string, args: unknown[] = []): Promise<ViewCallResult> {\n return this.client.viewCall(this.address, method, args);\n }\n\n /**\n * Send a state-changing transaction to the contract.\n *\n * @param method - The function name to call.\n * @param args - Arguments to pass.\n * @param opts - Optional: value to attach, gas limit, nonce, wallet override.\n * @returns A SentTx with `.hash` and `.wait()`.\n */\n async send(\n method: string,\n args: unknown[] = [],\n opts: {\n value?: string | number | bigint;\n gasLimit?: bigint;\n nonce?: bigint;\n wallet?: AsentumWallet;\n } = {},\n ): Promise<SentTx> {\n const signer = opts.wallet ?? this.wallet;\n if (!signer) {\n throw new Error(\n 'no wallet available — pass a wallet in opts or create the contract via wallet.deploy()',\n );\n }\n return signer.sendCall({\n to: this.address,\n method,\n args,\n value: opts.value,\n gasLimit: opts.gasLimit,\n nonce: opts.nonce,\n });\n }\n\n /**\n * Attach a wallet to this contract for future send() calls.\n */\n connect(wallet: AsentumWallet): AsentumContract {\n return new AsentumContract(this.client, this.address, this.deployTx, wallet);\n }\n\n /**\n * Get the source code of this contract as a UTF-8 string.\n * Returns null if the address has no deployed code.\n */\n async getSource(): Promise<string | null> {\n return this.client.getContractSource(this.address);\n }\n\n /**\n * Get the ASE balance of this contract.\n */\n async getBalance(): Promise<bigint> {\n const bal = await this.client.getBalance(this.address);\n return BigInt(bal.balance);\n }\n\n /**\n * Wait for the deploy transaction to be confirmed (if this contract\n * was deployed in this session). Useful after `wallet.deploy()`.\n */\n async waitForDeploy(timeoutMs = 15_000): Promise<Receipt> {\n if (!this.deployTx) {\n throw new Error('this contract was not deployed in this session — no deploy tx to wait for');\n }\n return this.deployTx.wait(timeoutMs);\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@asentum/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "TypeScript SDK for building on Asentum. Chain reads, wallet management, contract deployment and interaction. Works in Node.js and browsers.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": ["dist", "src", "README.md", "LICENSE"],
|
|
16
|
+
"keywords": ["asentum", "blockchain", "sdk", "dilithium", "post-quantum", "wallet", "ethereum-rpc"],
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/asentum-network/sdk.git"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://asentum.com",
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/asentum-network/sdk/issues"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsup",
|
|
30
|
+
"dev": "tsup --watch",
|
|
31
|
+
"test": "vitest run",
|
|
32
|
+
"test:watch": "vitest",
|
|
33
|
+
"typecheck": "tsc --noEmit",
|
|
34
|
+
"prepublishOnly": "npm run build"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@asentum/crypto": "^0.1.0",
|
|
38
|
+
"@asentum/types": "^0.1.0",
|
|
39
|
+
"@chainsafe/ssz": "^0.15.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/node": "^20.10.0",
|
|
43
|
+
"tsup": "^8.0.0",
|
|
44
|
+
"typescript": "^5.3.0",
|
|
45
|
+
"vitest": "^1.0.0"
|
|
46
|
+
}
|
|
47
|
+
}
|