Parts Bin
Difficulty: Beginner
Restock a warehouse shelf by supplying the exact part codes your bin still needs.
Objective
Register, read the bin payload, and deliver each code until the status flips to Stocked.
How to Join
Start with the Arkiv SDK quickstart so your tooling is ready. Fund your player wallet through the Mendoza faucet at https://mendoza.hoodi.arkiv.network/faucet/ and watch on-chain activity in the Mendoza explorer at https://explorer.mendoza.hoodi.arkiv.network/.
Export the public endpoints before launching scripts:
export ARKIV_RPC_URL=https://mendoza.hoodi.arkiv.network/rpc
export ARKIV_WS_URL=wss://mendoza.hoodi.arkiv.network/rpc/ws
Register by publishing an entity annotated with register_for="parts-bin" and team="<team_name>". The server provisions a bin entity for your team with annotations ctf="parts-bin", team, and bin_for. Read its payload to see a JSON object containing status, needs (array of codes), received, and updated_at.
Example registration snippet:
#!/usr/bin/env bun
import { createWalletClient, http, type Hex } from "@arkiv-network/sdk"
import { privateKeyToAccount } from "@arkiv-network/sdk/accounts"
import { mendoza } from "@arkiv-network/sdk/chains"
import { ExpirationTime, jsonToPayload } from "@arkiv-network/sdk/utils"
const SLUG = "parts-bin"
const RPC_URL = process.env.ARKIV_RPC_URL ?? "https://mendoza.hoodi.arkiv.network/rpc"
async function register(team: string): Promise<void> {
const privateKey = (process.env.ARKIV_PRIVATE_KEY ?? "").trim() as Hex
if (!privateKey) {
throw new Error("Set ARKIV_PRIVATE_KEY before running this script")
}
const account = privateKeyToAccount(privateKey)
const walletClient = createWalletClient({ chain: mendoza, transport: http(RPC_URL), account })
const { entityKey, txHash } = await walletClient.createEntity({
payload: jsonToPayload({ intent: "register" }),
contentType: "application/json",
attributes: [
{ key: "register_for", value: SLUG },
{ key: "team", value: team },
],
expiresIn: ExpirationTime.fromMinutes(10),
})
console.log(`Registered ${team} entity=${entityKey} tx=${txHash}`)
}
register("your-team-name").catch((error) => {
console.error(error)
process.exit(1)
})
Deliver parts by publishing entities annotated with supply_for_bin="<bin_id>" and team="<team_name>". The JSON body must be {"code": "<exact string from needs>"}. Codes can arrive in any order, and the bin is marked complete when needs becomes empty. A Discord announcement confirms your solve once the payload reads {"status": "Stocked" ...}.
Support
Questions? Drop a message in the #CTFs channel on Discord.