@ asentum/ sdk (英语)
Asentum 的 SDK 脚本类型 。 读取链条,用 Dilithium3(ML-DSA-65)签名, 发送交易, 跟随它们从“ 块中” 到“ 最终” 合同及其活动。 工作于Node.js 18+和现代浏览器.
以0.8.1为节点的当前.
npm install @asentum/sdk
快开始
import { AsentumClient, AsentumWallet, formatAse } from '@asentum/sdk';
const client = new AsentumClient('https://testnet.asentum.com');
// Reads need no keys
const { finalized, tip } = await client.getHeads();
const bal = await client.getBalance('ase1v0myp2de3dhj3crvkhxqlnjaw2mvp64a9efkpl');
console.log(formatAse(bal.balance), 'ASE at block', tip);
// A wallet signs locally; keys never leave your process
const wallet = AsentumWallet.fromSecretKey(client, SECRET_KEY_HEX, PUBLIC_KEY_HEX);
console.log(wallet.address); // ase1...
const tx = await wallet.sendTransfer({
to: 'ase1wtc569gfwk87hplaawr46uj4suwsx2wndgf8ue',
amountWei: 10n ** 18n, // 1 ASE
});
const receipt = await tx.wait(); // in a block, about 2.5 s
if (!receipt.success) throw new Error(receipt.error);
await tx.wait({ until: 'final' }); // final, a few blocks later
测试ASE来自空投仪表板(参见"Docs中的"Get Test ASE").
节点的 /dev/faucet 每个公共节点都关闭了.
连锁店的事
- 二头相. 这个 提示 是最佳链条上最新的块 这个
定稿 高度跟踪了大约3个街区 却从未改变过.
getHeads()返回两者. - 不接受.
POST /tx回复accepted: true仅限 意思是节点把交易放入了它的集合. 等着收据. - 收款使用情况
success一个布尔人。 没有status报告 收讫. 交易失败success: false还有一个error理由,你觉得呢. - 收据默认读取提示. 收据与
finalized: false实值 很少输给兄弟和交易土地 又是在后面的一个街区。 仅finalized: true这是永久的. - 通讯地址. SDK接受这个
ase1...或者说0x...随地而回 ase1 对于它的每个地址表面, 也是节点用六进制回答的地方 (接收、参与、委员会、治理)。 与 小写十六进制, 因此 SDK 在内部转换 ase1 地址 在签署或取景前,合同论据为六分法。 哈什和生字节 保持0xxx(他们没有ase1形式),合同内地址也一样 返回值和事件数据:用toAse1显示前 他们. - 数额 将 Wei (1 ASE = 10^18 Wei) 作为响应中的十进制字符串.
- 利率限制. 公共网关允许大约25个请求每秒
IP 并用 HTML 页面回答 429; 节点限制块并读取
到240分,然后4分一秒。 SDK重试429和5xx
在它抛出之前,先退后退
RateLimitError。 。 。 .
自动访问
const client = new AsentumClient(url?, {
retries: 3, // retries for 429 / 5xx / network errors
requestTimeoutMs: 30000,
fetch, // custom fetch, optional
headers: {}, // e.g. Authorization for a private RPC
});
每个方法都采用可选的最后一个参数 { signal?: AbortSignal, retries?: number }。 。 。 .
链与保健
| 方法 | 路线 | 回返 |
|---|---|---|
getHeads() | GET /v3/heads | { finalized: number, tip: number } |
getTipNumber() 编号 : getFinalizedNumber() | GET /v3/heads | number |
getBlockNumber() | GET /chain | 最终高度, number |
getChainInfo() | GET /chain | 链式 id、 最终高度、 集成池大小、 页眉 |
getChainId() | GET /chain | bigint (被夹住) |
getMetadata() | GET /metadata | EIP-3085 元数据 |
getApiInfo() | GET /api | 节点身份 |
getGenesis() | GET /genesis | 起源谱 |
isHealthy() | GET /health | boolean |
isReady() | GET /ready | boolean (在503上作假;注意节点0.8.1报告即使被搁置也准备就绪,所以请注意 getHeads()(中文(简体) ) |
账户
| 方法 | 路线 | 回返 |
|---|---|---|
getBalance(addr) | GET /balance/<addr> | { address, balance, nonce, pendingNonce } |
getNonce(addr, { pending? }) | GET /balance/<addr> | bigint,默认待决 |
getAccount(addr) | GET /asentum/account/<addr> | { exists, balance, nonce, codeHash, storageRoot, height } |
getPublicKeyStatus(addr) | GET /public-key/<addr> | { recorded, canOmitKey, ... } |
块
| 方法 | 路线 | 回返 |
|---|---|---|
getBlock(n, { tip? }) | GET /block/<n>[?tip=1] | Block | null (单位:千美元)finalized,以及 confirmations编号 :auraHash 在提示块上) |
getBlockReceipts(n, { tip? }) | GET /block/<n>/receipts | { receipts, finalized?, available } |
getRawBlock(n) | GET /block-raw/<n> | SSZ 六进制或 null |
getFinalizedStatus(h) | GET /v3/finalized?height= | { finalized, auraHash? } |
交易和收款
| 方法 | 路线 | 回返 |
|---|---|---|
getReceipt(hash, { finalizedOnly? }) | GET /receipts/<hash>[?tip=0] | Receipt | null (单位:千美元)success, (中文(简体) ), error?, (中文(简体) ), finalized, (中文(简体) ), confirmations, (中文(简体) ), blockHash, (中文(简体) ), auraHash?(中文(简体) ) |
waitForReceipt(hash, opts) | 民意调查 GET /receipts | Receipt (见下文) |
getTransaction(hash) | eth_getTransactionByHash | EthTransaction | null |
submitRawTx(rawTx) | POST /tx | { accepted, reason?, txHash? } |
submitRawTxBatch(rawTxs) | POST /tx/batch | { accepted, rejected, total, results } |
合同
| 方法 | 路线 | 回返 |
|---|---|---|
viewCall(contract, method, args, { blockTag? }) | POST /view | { ok, returnValue, reason?, blockNumber, finalized, ... } |
view(contract, method, args, { blockTag? }) | POST /view | 返回值; 抛出 ViewError |
getCode(addr) 编号 : getContractSource(addr) | eth_getCode | 十六进制/ 源文本 |
getStorageAt(addr, key) | eth_getStorageAt | 存储的文本或 null |
getLogs({ address, event, fromBlock, toBlock }) | eth_getLogs | 已解码 Log[] (仅确定区块;10 000个区块以上的区域被分割) |
blockTag 实值 'tip' (默认; 'latest' 财务报告和审定财务报表 'pending' 表示相同)或
'finalized' (单位:千美元)'safe') (中文(简体) ). 没有历史状态读取.
验证人、共识、治理
| 方法 | 路线 |
|---|---|
getValidators() | GET /validators (约260 KB) |
getParticipation({ lookback }) | GET /participation |
getCommittee({ epoch }) | GET /v3/committee |
getLiveness() | GET /consensus/liveness |
getTombstones() | GET /slashing/tombstones |
getProposals() 编号 : getProposal(id) | GET /governance/proposals, (中文(简体) ), /governance/proposal/<id> |
getGovernanceLocked(addr) 编号 : getGovernanceWithdrawable(addr) | GET /governance/locked/<addr>, (中文(简体) ), /governance/withdrawable/<addr> |
getGovernanceLibraries() 编号 : getGovernanceLibrary(name) | GET /governance/libraries, (中文(简体) ), /governance/library/<name> |
jsonRpc(method, params) | POST / (任何JSON-RPC方法) |
faucet() 已贬值: 它叫 /dev/faucet,它只对一个本地
打开它的德文网.
阿森通瓦尔特
const wallet = AsentumWallet.create(client); // random key
const wallet2 = AsentumWallet.fromSeed(client, seed32); // deterministic
const wallet3 = AsentumWallet.fromSecretKey(client, skHex, pkHex);
wallet.address; // ase1...
wallet.addressHex; // 0x... lowercase, what contracts see as msg.sender
wallet.secretKeyHex; // back this up like a password
wallet.publicKeyHex;
await wallet.getBalance(); // bigint wei
await wallet.getNonce(); // bigint, the node's pendingNonce
发送
await wallet.sendTransfer({ to, amountWei: 10n ** 18n });
await wallet.sendCall({ to: contract, method: 'swap', args: [...], valueWei: 0n });
const c = await wallet.deploy(source); // c.address is known right away
await c.waitForDeploy();
每次发送返回 { hash, nonce, from, contractAddress?, wait() } 一经
节点接受了,扔 TxRejectedError (与 reason当它
没有。 被拒绝的交易从未到达链.
数量. amountWei 编号 : valueWei 绝对是韦伊。 年长者 amount 编号 :
value 字段经过 parseAse: 数字或小数字符串是 ASE
(单位:千美元)'1.5' 表示 1.5 ASE , 表示比值为 Wei, 表示整数字符串超过 18
数字读作 wei. sendTransferWei 财务报告和审定财务报表 sendCallWei 仅取魏.
诺斯. 钱包询问节点 pendingNonce 手伸出来
相继的自来自来自出
钱包获取 n, n+1, n+2 。 拒绝之后,它又问节点
(单位:千美元)wallet.resetNonce() 用手做同样的事情。 过 nonce 以覆盖.
通过同一皇家警察部队提交和投票: pendingNonce 每个节点.
蝙蝠侠. 首先签名,然后在一个请求中提交:
const a = await wallet.signCall({ to, method: 'a' });
const b = await wallet.signCall({ to, method: 'b' });
const res = await wallet.sendBatch([a, b]); // POST /tx/batch
res.results[0].accepted; res.results[0].wait();
无密钥交易. 一旦连锁店有账户的公用钥匙
记录,它的交易可以留下密钥 大约三分之一
小一点. AsentumWallet.create(client, { keyless: 'auto' }) 切换到
尽快 getPublicKeyStatus().canOmitKey 这是真的。 默认是 'off'。 。 。 .
每个发送时其它覆盖 : gasLimit (违约:21 000美元用于转移,
200 000 000美元用于呼叫,至少200 000美元用于部署;合同呼叫需要
至少有50,000人, maxFeePerGas (违约1), signal。 。 。 .
名称 (@ 用户名)
从节点0.9.0和名称旗日(链条1423上的1 200 000块)a
账户可以拥有像 @milkie。地址上的名称点; 解析
当你建立交易 并在确认屏幕上显示.
if (await client.namesActive()) {
const { address, name } = await client.resolveRecipient('@milkie'); // throws NameNotFoundError for a free name
const primary = await client.lookupAddress(wallet.address); // "milkie" or null
}
在旗日之前,在0.9.0年以上的节点上,每一次仰望都抛出
NamesNotActiveError。 。 。 .
登记、转让和记录(0.3.1)
每篇书信都是签名的调用NameRegistry系统合同
(单位:千美元)NAME_REGISTRY_CONTRACT, (中文(简体) ), 0x...0b) (中文(简体) ). 钱包中每个都有一个方法:
await (await wallet.registerName('milkie')).wait(); // sends exactly nameFeeWei('milkie')
await wallet.transferName('milkie', 'ase1...'); // free; ase1 or 0x recipient
await wallet.setPrimaryName('milkie'); // the name apps show for this address
await wallet.clearPrimaryName();
await wallet.setNameRecord('milkie', 'x', '@asentum'); // keys: avatar, url, x, description; '' clears
| 方法 | 合同电话 | 页:1 |
|---|---|---|
registerName(name) | register(name) + 费用 | 500 / 100 / 50 ASE为3 / 4 / 5个字符,10 ASE为6个或以上的字符. 一半被烧了 一半被烧了 钱包的第一个名字变成了它的首要名称。 每43 200个区块每个地址最多登记5个. |
transferName(name, to) | transfer(name, to) | 只有主人,不收费。 名称停止为发件人的主机,其记录为新所有者清除. |
setPrimaryName(name) | setPrimary(name) | 只拥有者. |
clearPrimaryName() | clearPrimary() | 保持名称. |
setNameRecord(name, key, value) | setRecord(name, key, value) | 只拥有者. avatar 财务报告和审定财务报表 url 从https://、http://或ipfs://开始; x 是一个 X 手柄. |
每种方法都采用通常的发送选项(gasLimit, (中文(简体) ), nonce, (中文(简体) ), signal, (...) (中文(简体) )
返回 a SentTx; 调用 .wait() 为收据。 丢弃无效的名称
InvalidNameError 在签署之前.
读取: client.getNameLookup(name) (所有者、记录、主旗),
client.resolveName(name), (中文(简体) ), client.lookupAddress(address),或视图调用
例如 client.viewCall(NAME_REGISTRY_CONTRACT, 'isAvailable', ['milkie'])。 。 。 .
建立地名市场
登记处 无批准或操作方法: 只有主人可以移动 a
名称。 合同可以拥有自己的名字,所以市场可以充当代管人.
在合同中,登记处视市场为 msg.sender,则
市场移动名称 交叉合同呼叫,
E(registry).transfer(name, buyer)。 。 。 .
按此顺序列出,以便其他人不能在以下两者之间声称姓名:
- 卖方打电话
marketplace.prepare(name, price)市场检查E(registry).get(name).owner === msg.sender并记录卖方. - 卖方打电话
wallet.transferName(name, marketplaceAddress)。 。 。 . marketplace.activate(name)检查市场现在拥有这个名字.- 买家打电话
marketplace.buy(name)与价格。 市场支付 卖方和电话E(registry).transfer(name, buyer)。 。 。 . - 要取消,卖方打电话
marketplace.cancel(name)并获得名称 通过同样的转移.
每次转帐都清空记录 所以买家从清扫开始 简介.
已签名的消息
const proof = wallet.signMessage(challenge); // { address, publicKey, signature }
verifyMessage({ ...proof, message: challenge }); // true
签名的字节是 "Asentum Signed Message:\n" + byteLength(message) + "\n" + message (ML-DSA-65),与(a) window.asentum.signMessage 编辑
电报钱包,所以服务器 检查每个钱包的方式相同.
契约
import { AsentumContract } from '@asentum/sdk';
const pool = new AsentumContract(client, 'ase1v0myp2de3dhj3crvkhxqlnjaw2mvp64a9efkpl');
await pool.view('getPool', ['3']); // reads the tip
await pool.view('getPool', ['3'], { blockTag: 'finalized' });
await pool.viewFull('getPool', ['3']); // value, gas, events, blockNumber
const tx = await pool.connect(wallet).send('swapExactIn', [...], { valueWei });
await pool.getEvents('Swap', { fromBlock: 570000, toBlock: 571000 });
await pool.getSource();
await pool.getAccount(); // codeHash = BLAKE3 of the source
快速确认
交易在发送后大约在一个街区内(大约2.5) 后几条街(大约为7至10秒), 显示 第一点成功,第二点成功.
import { TimeoutError } from '@asentum/sdk';
const tx = await contract.send('swapExactIn', args);
setStatus(tx.hash, 'pending');
try {
await tx.wait({
until: 'final',
onIncluded: (r) => setStatus(tx.hash, r.success ? 'in-block' : 'failed'),
onReorg: () => setStatus(tx.hash, 'pending'), // its block lost; it will land again
onFinal: (r) => setStatus(tx.hash, r.success ? 'final' : 'failed'),
timeoutMs: 120_000,
signal, // AbortSignal, optional
});
} catch (e) {
if (e instanceof TimeoutError) setStatus(tx.hash, 'still-pending'); // not a failure
else throw e;
}
client.waitForReceipt(hash, options) 任何大麻都一样。 选项 :
| 选项 | 默认 | 含义 |
|---|---|---|
until | 'included' | 'included': 第一次收到时解决. 'final': 一次解决 finalized: true。 。 。 . |
timeoutMs | 60 000人/120 000人 | 拒绝使用 TimeoutError (单位:千美元)lastReceipt 如果在区块内,则设置. |
pollIntervalMs | 1 000个 | 区块相隔约2.5个;更快地买不到任何东西. |
onIncluded(r) | 在一个街区。 如果重置器移动到另一个街区,则再次起火. | |
onReorg(prev) | 它被一个兄弟弄丢了. | |
onFinal(r) | 最终(与 until: 'final') (中文(简体) ). | |
throwOnFailure | false | 拒绝方式 TxFailedError 打开 success: false 而不是解决. |
signal | 别等了AbortError) (中文(简体) ). 交易不受影响. | |
pauseWhenHidden | true | 在浏览器中,标签被隐藏时没有投票. |
传粉者在429和5xx上退后(在发送后重复,否则) 双倍至10 s),并持续地通过网络blips.
tx.wait() 没有争论的行为像0.1.x:它首先解决
收据(以块形式),包括失败的收据. tx.wait(ms) 仍然需要一个
暂停 .
错误
SDK 故意所抛出的所有错误 AsentumError 并携带
稳定 code数字 :
| 类 | 何时 |
|---|---|
TxRejectedError | POST /tx 已回复 accepted: false (单位:千美元)reason, (中文(简体) ), isNonceError(中文(简体) ) |
TxFailedError | 收据有 success: false (与 throwOnFailure(中文(简体) ) |
TimeoutError | 等待时间已耗尽(lastReceipt); tx 可能仍然着陆 |
AbortError | 您的中止信号已发射 |
ViewError | POST /view 已回复 ok: false |
RpcError | HTTP 200 带一个 error 机构(地址差、散列差、治理失败读取) |
JsonRpcError | a JSON-RPC 错误对象(rpcCode(中文(简体) ) |
RateLimitError | HTTP 429 复试后(retryAfterMs(中文(简体) ) |
HttpError | 任何其他非第-2xx项(status, (中文(简体) ), body(中文(简体) ) |
NetworkError | 获取失败或超时 |
"没有找到"不是一个错误: getReceipt, (中文(简体) ), getBlock, (中文(简体) ), getTransaction, (中文(简体) ),
getRawBlock 财务报告和审定财务报表 getProposal 返回时 null。 。 。 .
帮助者
import {
toAse1, toHexAddress, hexToAse1, ase1ToHex, isAse1, isHexAddress, isAddress, shortAse1,
ase1ArgsToHex, aseToWei, parseAse, formatAse, toWei, eventTopic, getContractAddress,
} from '@asentum/sdk';
toAse1('0x72f14d1509758feb87fdeb875d7255871d0329d3'); // 'ase1wtc569gfwk87hplaawr46uj4suwsx2wndgf8ue'
toHexAddress('ase1wtc569gfwk87hplaawr46uj4suwsx2wndgf8ue'); // '0x72f1...29d3'
ase1ArgsToHex(['ase1...', { owner: 'ase1...' }]); // every ase1 inside becomes 0x hex
aseToWei('1.5'); // 1500000000000000000n (always ASE)
formatAse(15n * 10n ** 17n); // '1.5'
eventTopic('Swap'); // topics[0] for eth_getLogs: BLAKE3 of the name
getContractAddress(wallet.address, 3n); // where a deploy with nonce 3 lands
从0.1.x升级
见 变动情况。简短清单: wallet.address 财务报告和审定财务报表
contract.address 现为 ase1 (addressHex 有六分之一,收据
sender编号 :recipient 为 ase1, getBlock 返回时 null 对于一个缺失的街区,
getReceipt 丢入运输错误而不是返回 null,则
水龙头帮手堕地.
如何运作
交易是SSZ编码,用 BLAKE3 散列,用 ML-DSA-65 签名
(锂3) 当地提交 POST /tx。交易
散列是已签名字节的 BLAKE3, 所以SDK 在节点之前就知道了
答对. 读取使用节点的REST路由,加上JSON-RPC用于代码,存储,
交易和日志。 见 节点 API 参考
财务报告和审定财务报表 快速确认。 。 。 .
发展
npm test # unit tests (mocked fetch)
npm run test:live # read-only smoke test against https://testnet.asentum.com
npm run typecheck
npm run build
许可证
阿帕奇 - 2.0