Skip to content

Commit

Permalink
Add faucet, map entry, members
Browse files Browse the repository at this point in the history
  • Loading branch information
aryzing committed Oct 14, 2024
1 parent 331f1cd commit 7f4a13a
Show file tree
Hide file tree
Showing 17 changed files with 234 additions and 75 deletions.
Binary file modified bun.lockb
Binary file not shown.
24 changes: 6 additions & 18 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
import {
accounts,
blocks,
info,
proofOfTransfer,
smartContracts,
stackingPool,
transactions,
} from "./stacks-api/index.js";
export const stacksApi = {
accounts,
blocks,
info,
proofOfTransfer,
smartContracts,
stackingPool,
transactions,
};
export { stacksApi } from "./stacks-api/index.js";
export type * as StacksApi from "./stacks-api/index.js";

export { stacksRpcApi } from "./stacks-rpc-api/index.js";
export type * as StacksRpcApi from "./stacks-rpc-api/index.js";

export { queries } from "./queries/index.js";

export * from "./utils/index.js";
9 changes: 7 additions & 2 deletions src/stacks-api/accounts/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
export { balances } from "./balances.js";
import { balances } from "./balances.js";
export type * as Balances from "./balances.js";

export { latestNonce } from "./latest-nonce.js";
import { latestNonce } from "./latest-nonce.js";
export type * as LatestNonce from "./latest-nonce.js";

export const accounts = {
balances,
latestNonce,
};
6 changes: 5 additions & 1 deletion src/stacks-api/blocks/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
export { getBlock } from "./get-block.js";
import { getBlock } from "./get-block.js";
export type * as GetBlock from "./get-block.js";

export const blocks = {
getBlock,
};
6 changes: 6 additions & 0 deletions src/stacks-api/faucets/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { stx } from "./stx.js";
export type * as Stx from "./stx.js";

export const faucets = {
stx,
};
47 changes: 47 additions & 0 deletions src/stacks-api/faucets/stx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { error, safePromise, success, type Result } from "../../utils/safe.js";
import type { ApiRequestOptions } from "../types.js";

export type Args = {
address: string;
stacking?: boolean;
} & ApiRequestOptions;

export async function stx(opts: Args): Promise<Result<any>> {
const search = new URLSearchParams();
search.append("address", opts.address);
if (opts.stacking) search.append("stacking", "true");

const init: RequestInit = {};
if (opts.apiKeyConfig) {
init.headers = {
[opts.apiKeyConfig.header]: opts.apiKeyConfig.key,
};
}
init.method = "POST";

const endpoint = `${opts.baseUrl}/extended/v1/faucets/stx?${search}`;
const res = await fetch(endpoint, init);

if (!res.ok) {
return error({
name: "FetchStxError",
message: "Failed to fetch STX.",
data: {
status: res.status,
statusText: res.statusText,
bodyParseResult: await safePromise(res.json()),
},
});
}

const [jsonError, data] = await safePromise(res.json());
if (jsonError) {
return error({
name: "ParseBodyError",
message: "Failed to parse response body as JSON.",
data: jsonError,
});
}

return success(data);
}
47 changes: 21 additions & 26 deletions src/stacks-api/index.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,34 @@
import { balances, latestNonce } from "./accounts/index.js";
export const accounts = { balances, latestNonce };
import { accounts } from "./accounts/index.js";
export type * as Accounts from "./accounts/index.js";

import { getBlock } from "./blocks/index.js";
export const blocks = { getBlock };
import { blocks } from "./blocks/index.js";
export type * as Blocks from "./blocks/index.js";

import { coreApi, poxDetails } from "./info/index.js";
export const info = { coreApi, poxDetails };
import { faucets } from "./faucets/index.js";
export type * as Faucets from "./faucets/index.js";

import { info } from "./info/index.js";
export type * as Info from "./info/index.js";

import {
cycle,
cycles,
signerInCycle,
signersInCycle,
stackersForSignerInCycle,
} from "./proof-of-transfer/index.js";
export const proofOfTransfer = {
cycle,
cycles,
signerInCycle,
signersInCycle,
stackersForSignerInCycle,
};
import { proofOfTransfer } from "./proof-of-transfer/index.js";
export type * as ProofOfTransfer from "./proof-of-transfer/index.js";

import { readOnly } from "./smart-contracts/index.js";
export const smartContracts = { readOnly };
import { smartContracts } from "./smart-contracts/index.js";
export type * as SmartContracts from "./smart-contracts/index.js";

import { members } from "./stacking-pool/index.js";
export const stackingPool = { members };
import { stackingPool } from "./stacking-pool/index.js";
export type * as StackingPool from "./stacking-pool/index.js";

import { addressTransactions, getTransaction } from "./transactions/index.js";
export const transactions = { addressTransactions, getTransaction };
import { transactions } from "./transactions/index.js";
export type * as Transactions from "./transactions/index.js";

export const stacksApi = {
accounts,
blocks,
faucets,
info,
proofOfTransfer,
smartContracts,
stackingPool,
transactions,
};
9 changes: 7 additions & 2 deletions src/stacks-api/info/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
export { coreApi } from "./core-api.js";
import { coreApi } from "./core-api.js";
export type * as CoreApi from "./core-api.js";

export { poxDetails } from "./pox-details.js";
import { poxDetails } from "./pox-details.js";
export type * as PoxDetails from "./pox-details.js";

export const info = {
coreApi,
poxDetails,
};
18 changes: 13 additions & 5 deletions src/stacks-api/proof-of-transfer/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
export { cycle } from "./cycle.js";
import { cycle } from "./cycle.js";
export type * as Cycle from "./cycle.js";

export { cycles } from "./cycles.js";
import { cycles } from "./cycles.js";
export type * as Cycles from "./cycles.js";

export { signerInCycle } from "./signer-in-cycle.js";
import { signerInCycle } from "./signer-in-cycle.js";
export type * as SignerInCycle from "./signer-in-cycle.js";

export { signersInCycle } from "./signers-in-cycle.js";
import { signersInCycle } from "./signers-in-cycle.js";
export type * as SignersInCycle from "./signers-in-cycle.js";

export { stackersForSignerInCycle } from "./stackers-for-signer-in-cycle.js";
import { stackersForSignerInCycle } from "./stackers-for-signer-in-cycle.js";
export type * as StackersForSignerInCycle from "./stackers-for-signer-in-cycle.js";

export const proofOfTransfer = {
cycle,
cycles,
signerInCycle,
signersInCycle,
stackersForSignerInCycle,
};
6 changes: 5 additions & 1 deletion src/stacks-api/smart-contracts/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
export { readOnly } from "./read-only.js";
import { readOnly } from "./read-only.js";
export type * as ReadOnly from "./read-only.js";

export const smartContracts = {
readOnly,
};
6 changes: 5 additions & 1 deletion src/stacks-api/stacking-pool/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
export { members } from "./members.js";
import { members } from "./members.js";
export type * as Members from "./members.js";

export const stackingPool = {
members,
};
30 changes: 13 additions & 17 deletions src/stacks-api/stacking-pool/members.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { error, safePromise, success, type Result } from "../../utils/safe.js";
import { type ApiRequestOptions } from "../types.js";
import { type ApiPaginationOptions, type ApiRequestOptions } from "../types.js";
import * as v from "valibot";

export type Options = {
export type Args = {
poolPrincipal: string;
afterBlock?: number;
unanchored?: boolean;
limit?: number;
offset?: number;
};
} & ApiRequestOptions &
ApiPaginationOptions;

export const memberSchema = v.object({
stacker: v.string(),
Expand All @@ -28,27 +29,22 @@ export const membersResponseSchema = v.object({
});
export type MembersResponse = v.InferOutput<typeof membersResponseSchema>;

export async function members(
opts: Options,
apiOpts: ApiRequestOptions,
): Promise<Result<MembersResponse>> {
export async function members(args: Args): Promise<Result<MembersResponse>> {
const search = new URLSearchParams();
if (opts.afterBlock) search.append("after_block", opts.afterBlock.toString());
if (opts.unanchored) search.append("unanchored", "true");
if (opts.limit) search.append("limit", opts.limit.toString());
if (opts.offset) search.append("offset", opts.offset.toString());
if (args.afterBlock) search.append("after_block", args.afterBlock.toString());
if (args.unanchored) search.append("unanchored", "true");
if (args.limit) search.append("limit", args.limit.toString());
if (args.offset) search.append("offset", args.offset.toString());

const init: RequestInit = {};
if (apiOpts.apiKeyConfig) {
if (args.apiKeyConfig) {
init.headers = {
[apiOpts.apiKeyConfig.header]: apiOpts.apiKeyConfig.key,
[args.apiKeyConfig.header]: args.apiKeyConfig.key,
};
}

const res = await fetch(
`${apiOpts.baseUrl}/extended/beta/stacking/${opts.poolPrincipal}/delegations?${search}`,
init,
);
const endpoint = `${args.baseUrl}/extended/v1/pox4/${args.poolPrincipal}/delegations?${search}`;
const res = await fetch(endpoint, init);

if (!res.ok) {
return error({
Expand Down
9 changes: 7 additions & 2 deletions src/stacks-api/transactions/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
export { addressTransactions } from "./address-transactions.js";
import { addressTransactions } from "./address-transactions.js";
export type * as AddressTransactions from "./address-transactions.js";

export { getTransaction } from "./get-transaction.js";
import { getTransaction } from "./get-transaction.js";
export type * as GetTransaction from "./get-transaction.js";

export type * as Common from "./schemas.js";

export const transactions = {
addressTransactions,
getTransaction,
};
8 changes: 8 additions & 0 deletions src/stacks-api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ export type ApiRequestOptions = {
apiKeyConfig?: ApiKeyConfig;
};

export type ProofAndTip = {
/**
* Returns object without the proof field when set to 0.
*/
proof?: number;
tip?: "latest" | string;
};

export type ApiPaginationOptions = {
/**
* The number of items to return. Each endpoint has its own maximum allowed
Expand Down
6 changes: 6 additions & 0 deletions src/stacks-rpc-api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { smartContracts } from "./smart-contracts/index.js";
export type * as SmartContracts from "./smart-contracts/index.js";

export const stacksRpcApi = {
smartContracts,
};
6 changes: 6 additions & 0 deletions src/stacks-rpc-api/smart-contracts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { mapEntry } from "./map-entry.js";
export type * as MapEntry from "./map-entry.js";

export const smartContracts = {
mapEntry,
};
72 changes: 72 additions & 0 deletions src/stacks-rpc-api/smart-contracts/map-entry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import type { ApiRequestOptions, ProofAndTip } from "../../stacks-api/types.js";
import { error, safePromise, success, type Result } from "../../utils/safe.js";
import * as v from "valibot";

export type Args = {
contractAddress: string;
contractName: string;
mapName: string;
mapKey: string;
} & ApiRequestOptions &
ProofAndTip;

const mapEntryResponseSchema = v.object({
/**
* Hex-encoded string of clarity value. It is always an optional tuple.
*/
data: v.string(),
/**
* Hex-encoded string of the MARF proof for the data
*/
proof: v.optional(v.string()),
});
export type MapEntryResponse = v.InferOutput<typeof mapEntryResponseSchema>;

export async function mapEntry(args: Args): Promise<Result<MapEntryResponse>> {
const search = new URLSearchParams();
if (args.proof === 0) search.append("proof", "0");
if (args.tip) search.append("tip", args.tip);

const init: RequestInit = {};
if (args.apiKeyConfig) {
init.headers = {
[args.apiKeyConfig.header]: args.apiKeyConfig.key,
};
}
init.method = "POST";
init.body = args.mapKey;

const endpoint = `${args.baseUrl}/v2/map_entry/${args.contractAddress}/${args.contractName}/${args.mapName}?${search}`;
const res = await fetch(endpoint, init);
if (!res.ok) {
return error({
name: "FetchMapEntryError",
message: "Failed to fetch map entry.",
data: {
status: res.status,
statusText: res.statusText,
bodyParseResult: await safePromise(res.json()),
},
});
}

const [jsonError, data] = await safePromise(res.json());
if (jsonError) {
return error({
name: "ParseBodyError",
message: "Failed to parse response body as JSON.",
data: jsonError,
});
}

const validationResult = v.safeParse(mapEntryResponseSchema, data);
if (!validationResult.success) {
return error({
name: "ValidateDataError",
message: "Failed to validate response data.",
data: validationResult,
});
}

return success(validationResult.output);
}

0 comments on commit 7f4a13a

Please sign in to comment.