feat: update batch api

This commit is contained in:
Kyle Fang
2025-02-08 03:43:50 +00:00
parent 15028e7709
commit 11161bb52e
2 changed files with 178 additions and 147 deletions

View File

@@ -1,3 +1,10 @@
/**
* WARNING:
*
* this file will be used in cross-runtime environments (browser, cloudflare workers, XLinkSDK, etc.),
* so please be careful when adding `import`s to it.
*/
import {
type ClarityValue,
type ContractPrincipalCV,
@@ -16,12 +23,19 @@ import {
mapName: string;
mapKey: ClarityValue;
}[];
readonly?: {
contract: ContractPrincipalCV;
functionName: string;
functionArgs: ClarityValue[];
}[];
index_block_hash?: string;
}
export interface BatchReadsResult {
variables: (ClarityValue | Error)[];
maps: (OptionalCV | Error)[];
tip: string;
vars: (ClarityValue | Error)[];
maps: (ClarityValue | Error)[];
readonly: (ClarityValue | Error)[];
}
export interface BatchApiOptions {
@@ -30,19 +44,47 @@ import {
const DEFAULT_STXER_API = 'https://api.stxer.xyz';
function convertResults(
rs: ({ Ok: string } | { Err: string })[],
): (ClarityValue | Error)[] {
const results: (ClarityValue | Error)[] = [];
for (const v of rs) {
if ('Ok' in v) {
results.push(deserializeCV(v.Ok));
} else {
results.push(new Error(v.Err));
}
}
return results;
}
export async function batchRead(
reads: BatchReads,
options: BatchApiOptions = {}
): Promise<BatchReadsResult> {
const payload: string[][] = [];
const ibh =
reads.index_block_hash == null
? undefined
: reads.index_block_hash.startsWith('0x')
? reads.index_block_hash.substring(2)
: reads.index_block_hash;
const payload: {
tip?: string;
vars: string[][];
maps: string[][];
readonly: string[][];
} = { vars: [], maps: [], readonly: [], tip: ibh };
if (reads.variables != null) {
for (const variable of reads.variables) {
payload.push([serializeCV(variable.contract), variable.variableName]);
payload.vars.push([serializeCV(variable.contract), variable.variableName]);
}
}
if (reads.maps != null) {
for (const map of reads.maps) {
payload.push([
payload.maps.push([
serializeCV(map.contract),
map.mapName,
serializeCV(map.mapKey),
@@ -50,56 +92,47 @@ import {
}
}
const ibh =
reads.index_block_hash == null
? null
: reads.index_block_hash.startsWith('0x')
? reads.index_block_hash.substring(2)
: reads.index_block_hash;
if (reads.readonly != null) {
for (const ro of reads.readonly) {
payload.readonly.push([
serializeCV(ro.contract),
ro.functionName,
...ro.functionArgs.map(v => serializeCV(v)),
]);
}
}
const url = `${options.stxerApi ?? DEFAULT_STXER_API}/sidecar/v2/batch-reads${
ibh == null ? '' : `?tip=${ibh}`
}`;
const url = `${options.stxerApi ?? DEFAULT_STXER_API}/sidecar/v2/batch`;
const data = await fetch(url, {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json',
},
});
const text = await data.text();
if (!text.includes('Ok') && !text.includes('Err')) {
throw new Error(
`Requesting batch reads failed: ${text}, url: ${url}, payload: ${JSON.stringify(
payload
)}`
payload,
)}`,
);
}
const results = JSON.parse(text) as [{ Ok: string } | { Err: string }];
const rs: BatchReadsResult = {
variables: [],
maps: [],
const rs = JSON.parse(text) as {
tip: string;
vars: ({ Ok: string } | { Err: string })[];
maps: ({ Ok: string } | { Err: string })[];
readonly: ({ Ok: string } | { Err: string })[];
};
return {
tip: rs.tip,
vars: convertResults(rs.vars),
maps: convertResults(rs.maps),
readonly: convertResults(rs.readonly),
};
let variablesLength = 0;
if (reads.variables != null) {
variablesLength = reads.variables.length;
for (let i = 0; i < variablesLength; i++) {
const result = results[i];
if ('Ok' in result) {
rs.variables.push(deserializeCV(result.Ok));
} else {
rs.variables.push(new Error(result.Err));
}
}
}
if (reads.maps != null) {
for (let i = 0; i < reads.maps.length; i++) {
const result = results[i + variablesLength];
if ('Ok' in result) {
rs.maps.push(deserializeCV(result.Ok) as OptionalCV);
} else {
rs.maps.push(new Error(result.Err));
}
}
}
return rs;
}
export interface BatchReadonlyRequest {
@@ -128,8 +161,7 @@ import {
? req.index_block_hash.substring(2)
: req.index_block_hash;
const url = `${options.stxerApi ?? DEFAULT_STXER_API}/sidecar/v2/batch-readonly${
ibh == null ? '' : `?tip=${ibh}`
const url = `${options.stxerApi ?? DEFAULT_STXER_API}/sidecar/v2/batch-readonly${ibh == null ? '' : `?tip=${ibh}`
}`;
const data = await fetch(url, {
method: 'POST',
@@ -154,4 +186,3 @@ import {
}
return rs;
}

View File

@@ -118,7 +118,7 @@ import {
async function main() {
await batchReadsExample();
await batchReadonlyExample();
// await batchReadonlyExample();
}
if (require.main === module) {