Thank you for contributing to GuildPass SDK.
GuildPass SDK V2 is the official TypeScript SDK for interacting with the GuildPass ecosystem. The current SDK is being rebuilt as a smaller, Stellar-first package with a strong focus on predictable APIs, strict typing, runtime safety, low dependency overhead, and independently testable modules.
This guide explains how to contribute to the current V2 codebase.
Please read:
README.mdCODE_OF_CONDUCT.mdSECURITY.md
If you are working from an issue, read the full issue before starting.
GuildPass campaign issues normally define:
- the problem;
- the expected outcome;
- suggested implementation boundaries;
- acceptance criteria;
- likely affected files;
- an independence requirement.
Treat the issue as the primary source of truth for your contribution.
GuildPass SDK V2 is a clean rebuild of the previous SDK.
The current direction is:
- TypeScript-first;
- Stellar-first;
- ESM-first;
- runtime-safe public APIs;
- minimal runtime dependencies;
- small independently testable modules;
- predictable public exports;
- compatibility with modern JavaScript runtimes.
The previous SDK contained functionality such as:
- ethers adapters;
- viem adapters;
- SIWE;
- EIP-712;
- EVM contract providers;
- multicall infrastructure;
- generic multichain abstractions.
Those are not part of the default V2 architecture.
Do not restore legacy V1 functionality unless an issue explicitly asks for it.
The current SDK V2 structure is intentionally small.
guildpass-sdk/
│
├── src/
│ ├── client/
│ ├── config/
│ ├── errors/
│ ├── stellar/
│ ├── testing/
│ ├── transport/
│ ├── types/
│ └── index.ts
│
├── tests/
├── logo/
├── .github/
├── package.json
├── pnpm-lock.yaml
├── tsconfig.json
├── tsup.config.ts
├── vitest.config.ts
├── README.md
├── CONTRIBUTING.md
├── CODE_OF_CONDUCT.md
├── SECURITY.md
└── LICENSE
Some directories may be introduced or expanded as new features are added.
A pull request should solve one issue.
Avoid combining unrelated:
- features;
- refactors;
- formatting changes;
- dependency upgrades;
- documentation rewrites;
- tooling changes.
Small PRs are easier to review, test, and merge.
GuildPass contributor issues are intentionally designed so different contributors can work concurrently.
Do not make your implementation depend on another open issue unless the issue explicitly requires it.
Do not import code from another contributor's unmerged branch.
If your task needs a small helper that does not yet exist, implement the minimum self-contained functionality required for your issue.
Anything exported through:
src / index.ts;should be treated as part of the SDK's public contract.
Do not export internal helpers simply because they are reusable internally.
Before adding a public export, consider whether SDK consumers genuinely need it.
Use TypeScript deliberately.
Prefer:
- discriminated unions;
- explicit interfaces;
- readonly values where appropriate;
- narrow function contracts;
unknownat untrusted boundaries;- runtime validation where TypeScript alone is insufficient.
Avoid:
- unnecessary
any; - broad unsafe casts;
as unknown as;- suppressing type errors instead of fixing them.
TypeScript types disappear at runtime.
Any data coming from:
- HTTP responses;
- user configuration;
- Stellar values;
- encoded payloads;
- external APIs;
should be treated as untrusted until validated.
SDK dependencies affect every application that installs the package.
Before adding a runtime dependency, consider:
- whether the platform already provides the required functionality;
- whether the functionality can be implemented safely in a small local module;
- bundle-size impact;
- browser/runtime compatibility;
- maintenance status;
- security implications.
New runtime dependencies should be justified in the PR description.
Equivalent inputs should produce equivalent outputs.
Avoid behaviour that unnecessarily depends on:
- object insertion order;
- global mutable state;
- system time;
- uncontrolled randomness;
- network availability.
Where time or randomness is needed, design it so tests can control it.
Install:
- Git
- Node.js 24 or newer
- pnpm 11.x
Check your versions:
node --version
pnpm --versionThe repository currently uses:
pnpm 11.16.0
Fork:
Adamantine-guild/guildpass-sdk
Then clone your fork:
git clone https://github.com/<YOUR_USERNAME>/guildpass-sdk.git
cd guildpass-sdkAdd the upstream repository:
git remote add upstream https://github.com/Adamantine-guild/guildpass-sdk.gitVerify:
git remote -vYou should have:
origin your fork
upstream Adamantine-guild/guildpass-sdk
Before creating a feature branch:
git checkout main
git fetch upstream
git pull upstream main
git push origin mainAlways branch from the latest main.
Do not work directly on main.
Recommended branch prefixes:
feat/
fix/
test/
docs/
refactor/
chore/
ci/
Examples:
git checkout -b feat/stellar-account-parsergit checkout -b feat/request-transportgit checkout -b fix/config-validationRun:
pnpm installFor reproducible verification:
pnpm install --frozen-lockfilepnpm may request approval for expected dependency build scripts.
If required:
pnpm approve-buildsOnly approve packages you recognise and that are required by the SDK toolchain.
pnpm typecheckThis runs TypeScript without producing build output.
pnpm buildThe SDK uses tsup.
Current build output includes:
dist/index.js
dist/index.js.map
dist/index.d.ts
Do not edit files inside dist/ manually.
pnpm testThe SDK uses Vitest.
pnpm test:watchpnpm devThis runs tsup in watch mode.
pnpm lintpnpm formatBefore opening a pull request, run:
pnpm install --frozen-lockfile
pnpm typecheck
pnpm build
pnpm testAll applicable checks should pass.
If your contribution changes linted files, also run:
pnpm lintTests are part of the implementation.
New behaviour should include appropriate tests.
Tests should cover, where relevant:
- expected behaviour;
- malformed input;
- boundary values;
- deterministic ordering;
- cancellation;
- timeouts;
- concurrency;
- security-sensitive input;
- runtime type failures.
Bug fixes should preferably include a regression test demonstrating the previous failure.
Prefer isolated tests that do not depend on external services.
For most SDK utilities:
Input
│
▼
Module
│
▼
Deterministic output
should be testable without:
- network access;
- GuildPass Core running;
- Stellar RPC;
- Redis;
- PostgreSQL.
Mock external behaviour only where the issue genuinely concerns integration boundaries.
GuildPass SDK V2 is Stellar-first.
When implementing Stellar functionality:
- validate real Stellar formats rather than only prefixes;
- distinguish supported and unsupported StrKey types;
- avoid unnecessary network requests;
- keep network-specific functionality isolated;
- avoid introducing EVM dependencies unless explicitly requested.
For example, this is not sufficient validation:
address.startsWith("G");Proper Stellar validation should use the appropriate encoding and checksum rules.
The SDK client should remain a thin developer-facing interface.
A client method should typically:
Validate caller input
│
▼
Build request
│
▼
Use transport
│
▼
Validate response
│
▼
Return typed result
Avoid embedding unrelated:
- retry logic;
- validation logic;
- request serialisation;
- domain calculations;
directly inside every client method.
Reusable behaviour should live in focused modules.
Transport code should remain independent of GuildPass domain endpoints where possible.
Transport concerns include:
- HTTP methods;
- headers;
- URL construction;
- timeouts;
- cancellation;
- response parsing;
- transport errors.
Transport modules should not contain membership or governance business logic.
Public SDK errors should be predictable.
Prefer:
- stable error codes;
- structured metadata;
- safe public messages;
- preserved causes internally where useful.
Do not expose:
- raw credentials;
- private keys;
- authentication headers;
- arbitrary secret-bearing objects;
- sensitive raw payloads.
Do not make consumers parse free-form error strings to determine error categories.
Take additional care when working on:
- Stellar signatures;
- authentication;
- capability tokens;
- webhook verification;
- API keys;
- cryptographic hashing;
- request signing;
- secret handling;
- replay protection.
Security-sensitive changes should include targeted failure tests.
SDK operations that may wait on external work should use AbortSignal where appropriate.
Cancellation behaviour should be explicit.
Do not silently swallow caller cancellation.
Distinguish between:
- caller cancellation;
- timeout;
- transport failure;
where the public API needs to expose those differences.
Timeout behaviour should be:
- bounded;
- documented;
- testable;
- distinct from ordinary request failure.
Avoid tests that depend on long real-time waits when controllable time or small deterministic timers can be used instead.
Concurrency-sensitive utilities should define their atomic behaviour.
Examples include:
- request deduplication;
- batching;
- async task scheduling;
- cache coordination.
Avoid naive:
check
then set
patterns where concurrent callers can race.
SDK code should avoid unexpectedly mutating caller-owned objects.
Prefer defensive copies for:
- configuration;
- headers;
- arrays;
- metadata;
- registry definitions.
Public APIs should document mutation behaviour when mutation is unavoidable.
Avoid unnecessary reliance on Node-only APIs in code intended to run in browser-compatible environments.
Prefer standard APIs such as:
fetch;AbortController;URL;URLSearchParams;- Web-compatible cryptographic APIs where appropriate.
Node-specific behaviour should be introduced only when clearly required.
The SDK currently builds as ESM.
The public package entry point is:
dist/index.js
with declarations:
dist/index.d.ts
Do not add CommonJS output unless there is a documented compatibility requirement.
Public SDK exports are defined through:
src / index.ts;Avoid deep imports such as:
import { something } from "@guildpass/sdk/src/internal";Consumers should use documented package exports only.
If you add a dependency, explain in your PR:
- why it is needed;
- why existing platform APIs are insufficient;
- whether it is runtime or development-only;
- any impact on bundle size;
- any security or compatibility implications.
Avoid adding large dependencies to solve small utility problems.
Prefer:
- small focused functions;
- explicit naming;
- readable control flow;
- clear public contracts;
- limited side effects;
- meaningful tests.
Avoid comments that merely repeat what the code already says.
Comments are most useful when documenting:
- security assumptions;
- non-obvious edge cases;
- protocol requirements;
- compatibility decisions.
Use clear scoped commit messages.
Recommended format:
type(scope): description
Examples:
feat(stellar): add Stellar account parser
feat(transport): add timeout-aware request handling
fix(config): reject malformed base URLs
test(validation): cover nested response failures
docs(sdk): update contribution guide
Push your branch:
git push origin <YOUR_BRANCH>Then open a pull request against:
Adamantine-guild/guildpass-sdk
Target:
main
Reference the issue using:
Closes #123
A good PR should explain:
Describe the implementation.
Explain the problem being solved.
List the commands you ran.
For example:
pnpm typecheck
pnpm build
pnpm test
Document any:
- trade-offs;
- security decisions;
- compatibility implications;
- intentionally excluded functionality.
Do not expand an issue significantly beyond its acceptance criteria.
If you discover another problem:
- mention it separately;
- suggest or create another issue;
- keep the current PR focused.
Many GuildPass SDK campaign issues contain an Independence Requirement.
This means your implementation must:
- work from the current
main; - not wait for another open issue;
- not depend on another contributor's branch;
- remain independently mergeable.
This requirement exists so multiple contributors can work concurrently.
GuildPass SDK uses GitHub Actions to validate changes.
The expected CI path is:
Install dependencies
│
▼
Typecheck
│
▼
Build
│
▼
Tests
Pull requests with failing required checks are not ready to merge.
GuildPass repositories use central PR automation maintained by Adamantine Guild.
The automation can:
- inspect workflow status;
- detect failed checks;
- wait for pending checks;
- detect merge conflicts;
- comment when intervention is required;
- merge eligible pull requests.
CI should be treated as part of the contribution contract.
Changes under:
.github/workflows/
are security-sensitive.
Do not modify workflows as part of an unrelated feature.
Workflow changes may require manual maintainer review because they can affect repository permissions and automation behaviour.
Update documentation when your change materially affects:
- installation;
- public SDK APIs;
- configuration;
- runtime behaviour;
- supported Stellar behaviour;
- contributor workflow.
Do not document functionality that has not actually been implemented unless it is clearly labelled as planned.
Do not report vulnerabilities through public issues.
Follow:
SECURITY.md
for responsible disclosure instructions.
All contributors must follow:
CODE_OF_CONDUCT.md
If an issue is unclear, ask a focused question on the issue before implementing a substantially different interpretation.
Avoid large speculative pull requests without alignment.
Thank you for helping build GuildPass SDK V2.