@1money/protocol-ts-sdk 2.1.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -1,28 +1,115 @@
1
- # Repository Guidelines
2
-
3
- ## Project Structure & Module Organization
4
- Core TypeScript sources live in `src/`, with domain folders for `api/`, `client/`, and shared `utils/`. Entry points such as `src/index.ts` stitch those modules together, while accompanying specs sit in sibling `__test__` directories (`src/api/tokens/__test__/index.test.ts`, etc.). Compiled artifacts are emitted to `es/` (ESM), `lib/` (CJS), and `umd/` for CDN usage, so never edit those outputs directly. Reference assets reside in `public/`, examples in `examples/`, and longer-form docs in `docs/`. Build behavior is centralized in `omni.config.js`, bundling tweaks in `rollup.config.js`, and TypeScript settings in `tsconfig.json`.
5
-
6
- ## Build, Test & Development Commands
7
- Use your preferred package manager, but stay consistent per branch.
8
- ```bash
9
- pnpm install # or npm install install dev + peer tooling
10
- npm run build # omni build -> emits es/lib/umd bundles
11
- npm run build:remote # same build with RUN_ENV=remote for hosted targets
12
- npm test # nyc + mocha using .mocharc.js
13
- npm run lint # prettier check + eslint (ts/tsx)
14
- npm run lint:fix # applies prettier/eslint autofixes
15
- ```
16
- Run linting before opening a PR; CI expects clean output directories.
17
-
18
- ## Coding Style & Naming Conventions
19
- The repo enforces `.editorconfig` (LF, UTF-8, two-space indents) and `prettier.config.js` (tabWidth 2, printWidth 50, single quotes, arrowParens `avoid`, trailing commas `none`). ESLint runs with `@typescript-eslint` rules over `src/**`. Prefer descriptive module exports (`api/checkpoints`, `client/rpc`) and keep test files named `*.test.ts`. Public APIs should expose camelCase functions, PascalCase classes, and never leak internal helper names.
20
-
21
- ## Testing Guidelines
22
- All specs use Mocha + Chai and live beside their subjects (`__test__/`). Structure tests as `describe('<module>')` blocks with explicit success/error cases that mirror the SDK’s `.success/.timeout/.error` flow. Execute `npm test` locally; NYC writes reports to `.nyc_output/` and enforces the existing coverage baselines, so add scenarios rather than loosening thresholds. When adding a module, stub network calls and favor deterministic fixtures.
23
-
24
- ## Commit & Pull Request Guidelines
25
- Commitlint extends the conventional config with allowed types such as `feat`, `fix`, `docs`, `refactor`, `test`, `chore`, plus the project tag `[1MONEY-PROTOCOL-TS-SDK]`. Format messages as `type(scope): summary`, e.g., `feat(api): add token metadata endpoint`. Before pushing, run `npm run lint && npm test` and ensure generated bundles are excluded from diffs. PRs should describe the change, list validation commands, link related issues, and include API or screenshot evidence when touching user-facing behavior.
26
-
27
- ## Security & Configuration Tips
28
- Never commit `.env` values; tests should rely on mocked data or public endpoints. When debugging against live protocol nodes, set `RUN_ENV=remote` only in your shell and prefer the `testnet` client configuration shown in `README.md`. Audit dependencies before enabling new wallets or transports, and keep peer versions (`axios`, `viem`, `@ethereumjs/rlp`) aligned with the ranges declared in `package.json`.
1
+ # AGENTS.md
2
+
3
+ This file provides guidance to CODE AGENT when working with code in this repository.
4
+
5
+ ## Keeping Docs & Skills in Sync (required)
6
+
7
+ **Any code change that adds or alters public behavior MUST update the docs and the
8
+ `skills/1money-protocol-sdk` skill in the same change.** The skill is what teaches
9
+ agents to consume the SDK correctly stale skill content produces wrong code.
10
+
11
+ Update the matching file(s) when you touch:
12
+
13
+ | Code change | Update |
14
+ | --- | --- |
15
+ | Read endpoint added/changed (`src/api/**`) | `skills/1money-protocol-sdk/references/api-reference.md` |
16
+ | Transaction builder or signing changed (`src/signing/**`) | `skills/1money-protocol-sdk/references/transactions.md` |
17
+ | Client/promise-wrapper, error, config, network, or utils (`src/client/**`, `src/utils/**`) | `skills/1money-protocol-sdk/references/client-and-errors.md` |
18
+ | New/removed public export or import subpath (`src/index.ts`, `/api`, `/client`, `/utils`) | `skills/1money-protocol-sdk/SKILL.md` (the import map + builder→endpoint table) |
19
+ | Commands, architecture, or conventions | this `AGENTS.md` (and the module `README.md`) |
20
+
21
+ Checklist before opening a PR: function signatures, the builder→endpoint table in
22
+ `SKILL.md`, enum values, and code examples still match the source. Also update the
23
+ affected module `README.md` and `src/__integration__/QUICKSTART.md` if the public
24
+ flow changed.
25
+
26
+ ## Development Commands
27
+
28
+ ### Building
29
+ - `npm run build` - Build the project using omni build tool (generates lib/, es/, and umd/ directories)
30
+ - `npm run build:remote` - Build for remote deployment with RUN_ENV=remote
31
+
32
+ ### Testing
33
+ - `npm test` - Run unit tests (nyc + Mocha, config `.mocharc.js`)
34
+ - `npm run test:integration` - Run integration tests against a live network
35
+ (`.mocharc.integration.js`, requires `RUN_INTEGRATION_TESTS=true`)
36
+ - `npm run test:integration:testnet` / `:local` - Pin the integration network
37
+ - `npm run test:all` - Unit + integration
38
+ - Unit tests live in `src/**/__test__/*.ts`; integration suite in `src/__integration__/`
39
+ (see its `QUICKSTART.md`)
40
+ - TS is loaded via `mocha.tsx.js` (tsx CJS transform) + `tsconfig-paths/register`;
41
+ `.mocharc.js` disables Node 22 strip-types so tsx resolves paths correctly
42
+
43
+ ### Linting & Code Quality
44
+ - `npm run lint` - Run both Prettier and ESLint checks
45
+ - `npm run lint:fix` - Auto-fix Prettier and ESLint issues
46
+ - `npm run lint:es` - ESLint TypeScript files in src/
47
+ - `npm run lint:prettier` - Check Prettier formatting
48
+ - Individual fix commands: `lint:es_fix`, `lint:prettier_fix`
49
+
50
+ ### Development Workflow
51
+ - `npm run new` - Generate new components using omni CLI
52
+ - `npm run release` - Release package using omni tool
53
+
54
+ ## Project Architecture
55
+
56
+ This is a TypeScript SDK for the 1Money Network Protocol with a modular architecture:
57
+
58
+ ### Core Structure
59
+ - **src/index.ts** - Main entry point, exports api client and utilities
60
+ - **src/api/** - API client modules for different endpoints (accounts, tokens, transactions, checkpoints, chain)
61
+ - **src/client/** - Core HTTP client with promise wrapper system
62
+ - **src/signing/** - Transaction signing: EIP-712 (`eip712/`), payload `builders/`, `signer.ts`, `core.ts`
63
+ - **src/utils/** - Helpers: address derivation, tx hashing, `encode.ts`, `memo/`
64
+
65
+ ### Key Architecture Patterns
66
+
67
+ #### API Client Pattern
68
+ The main `api()` function creates a configured client that returns typed API modules. It supports:
69
+ - Network selection (mainnet/testnet/local) with automatic base URL switching
70
+ - Configurable timeouts
71
+ - Modular API endpoints (accounts, tokens, transactions, checkpoints, chain)
72
+
73
+ #### Promise Wrapper System
74
+ Uses a custom promise wrapper in `src/client/core.ts` that provides:
75
+ - `.success()`, `.error()`, `.timeout()`, `.rest()` handlers
76
+ - Support for both traditional promise chains and async/await
77
+ - Structured error handling with typed responses
78
+
79
+ #### Module Organization
80
+ Each API module (accounts, tokens, etc.) has:
81
+ - `index.ts` - API methods
82
+ - `types.ts` - TypeScript interfaces
83
+ - `__test__/index.test.ts` - Unit tests
84
+ - `README.md` - Module documentation
85
+
86
+ ### Build System
87
+ - Uses **omni-door CLI** for build orchestration
88
+ - **Rollup** for bundling with multiple output formats:
89
+ - CommonJS (`lib/`)
90
+ - ES Modules (`es/`)
91
+ - UMD bundle (`umd/1money-protocol-ts-sdk.min.js`)
92
+ - **tsc-alias** for path alias resolution
93
+ - External dependencies: axios, viem, @ethereumjs/rlp (peer dependencies)
94
+
95
+ ### TypeScript Configuration
96
+ - Target: ESNext with strict mode enabled
97
+ - Path aliases: `@/*` maps to `src/*`
98
+ - Generates declaration files (.d.ts)
99
+ - Excludes test files from compilation
100
+
101
+ ### Testing Strategy
102
+ - Uses Mocha with nyc for coverage
103
+ - Tests located alongside source files in `__test__/` directories
104
+ - Supports both TypeScript and JavaScript test files
105
+ - 60-second timeout for async operations
106
+
107
+ ## Code Style & Commits
108
+
109
+ - Prettier (`prettier.config.js`): 2-space, **printWidth 50**, single quotes,
110
+ no trailing commas, `arrowParens: avoid`, semicolons on.
111
+ - ESLint (`@typescript-eslint`) over `src/`.
112
+ - Commits follow conventional format `type(scope): summary`; allowed types are in
113
+ `commitlint.config.js` (`feat`, `fix`, `chore`, `optimize`, `[1MONEY-PROTOCOL-TS-SDK]`, …).
114
+ - Husky hooks run automatically: `pre-commit` → lint-staged, `commit-msg` → `npm run lint:commit`,
115
+ plus a `pre-push` check. Don't bypass them.
package/CLAUDE.md CHANGED
@@ -1,77 +1 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Development Commands
6
-
7
- ### Building
8
- - `npm run build` - Build the project using omni build tool (generates lib/, es/, and umd/ directories)
9
- - `npm run build:remote` - Build for remote deployment with RUN_ENV=remote
10
-
11
- ### Testing
12
- - `npm test` - Run all tests using Mocha with nyc coverage
13
- - Tests are located in `src/**/__test__/*.ts` files
14
- - Uses Mocha with TypeScript support via tsx loader
15
-
16
- ### Linting & Code Quality
17
- - `npm run lint` - Run both Prettier and ESLint checks
18
- - `npm run lint:fix` - Auto-fix Prettier and ESLint issues
19
- - `npm run lint:es` - ESLint TypeScript files in src/
20
- - `npm run lint:prettier` - Check Prettier formatting
21
- - Individual fix commands: `lint:es_fix`, `lint:prettier_fix`
22
-
23
- ### Development Workflow
24
- - `npm run new` - Generate new components using omni CLI
25
- - `npm run release` - Release package using omni tool
26
-
27
- ## Project Architecture
28
-
29
- This is a TypeScript SDK for the 1Money Network Protocol with a modular architecture:
30
-
31
- ### Core Structure
32
- - **src/index.ts** - Main entry point, exports api client and utilities
33
- - **src/api/** - API client modules for different endpoints (accounts, tokens, transactions, checkpoints, chain)
34
- - **src/client/** - Core HTTP client with promise wrapper system
35
- - **src/utils/** - Utility functions for signing, address derivation, transaction hashing
36
-
37
- ### Key Architecture Patterns
38
-
39
- #### API Client Pattern
40
- The main `api()` function creates a configured client that returns typed API modules. It supports:
41
- - Network selection (mainnet/testnet/local) with automatic base URL switching
42
- - Configurable timeouts
43
- - Modular API endpoints (accounts, tokens, transactions, checkpoints, chain)
44
-
45
- #### Promise Wrapper System
46
- Uses a custom promise wrapper in `src/client/core.ts` that provides:
47
- - `.success()`, `.error()`, `.timeout()`, `.rest()` handlers
48
- - Support for both traditional promise chains and async/await
49
- - Structured error handling with typed responses
50
-
51
- #### Module Organization
52
- Each API module (accounts, tokens, etc.) has:
53
- - `index.ts` - API methods
54
- - `types.ts` - TypeScript interfaces
55
- - `__test__/index.test.ts` - Unit tests
56
- - `README.md` - Module documentation
57
-
58
- ### Build System
59
- - Uses **omni-door CLI** for build orchestration
60
- - **Rollup** for bundling with multiple output formats:
61
- - CommonJS (`lib/`)
62
- - ES Modules (`es/`)
63
- - UMD bundle (`umd/1money-protocol-ts-sdk.min.js`)
64
- - **tsc-alias** for path alias resolution
65
- - External dependencies: axios, viem, @ethereumjs/rlp (peer dependencies)
66
-
67
- ### TypeScript Configuration
68
- - Target: ESNext with strict mode enabled
69
- - Path aliases: `@/*` maps to `src/*`
70
- - Generates declaration files (.d.ts)
71
- - Excludes test files from compilation
72
-
73
- ### Testing Strategy
74
- - Uses Mocha with nyc for coverage
75
- - Tests located alongside source files in `__test__/` directories
76
- - Supports both TypeScript and JavaScript test files
77
- - 60-second timeout for async operations
1
+ @AGENTS.md
@@ -1,5 +1,5 @@
1
1
  export declare const TESTNET_API_URL = "https://api.testnet.1money.network";
2
- export declare const MAINNET_API_URL = "https://api.1money.network";
2
+ export declare const MAINNET_API_URL = "https://api.mainnet.1money.network";
3
3
  export declare const LOCAL_API_URL = "http://localhost:18555";
4
4
  export declare const CHAIN_IDS: {
5
5
  readonly MAINNET: 21210;
package/es/api/index.js CHANGED
@@ -355,7 +355,7 @@ function setInitConfig(config) {
355
355
  }
356
356
  client.axios;// Base URLs for the API
357
357
  const TESTNET_API_URL = 'https://api.testnet.1money.network';
358
- const MAINNET_API_URL = 'https://api.1money.network';
358
+ const MAINNET_API_URL = 'https://api.mainnet.1money.network';
359
359
  const LOCAL_API_URL = 'http://localhost:18555';
360
360
  // API version
361
361
  const API_VERSION = 'v1';const API_PREFIX$4 = `/${API_VERSION}/accounts`;
package/es/index.js CHANGED
@@ -1424,7 +1424,7 @@ var client$1 = {
1424
1424
  axiosStatic
1425
1425
  };// Base URLs for the API
1426
1426
  const TESTNET_API_URL = 'https://api.testnet.1money.network';
1427
- const MAINNET_API_URL = 'https://api.1money.network';
1427
+ const MAINNET_API_URL = 'https://api.mainnet.1money.network';
1428
1428
  const LOCAL_API_URL = 'http://localhost:18555';
1429
1429
  // API version
1430
1430
  const API_VERSION = 'v1';const API_PREFIX$4 = `/${API_VERSION}/accounts`;
@@ -1,5 +1,5 @@
1
1
  export declare const TESTNET_API_URL = "https://api.testnet.1money.network";
2
- export declare const MAINNET_API_URL = "https://api.1money.network";
2
+ export declare const MAINNET_API_URL = "https://api.mainnet.1money.network";
3
3
  export declare const LOCAL_API_URL = "http://localhost:18555";
4
4
  export declare const CHAIN_IDS: {
5
5
  readonly MAINNET: 21210;
package/lib/api/index.js CHANGED
@@ -478,7 +478,7 @@ function setInitConfig(config) {
478
478
  }
479
479
  client.axios;// Base URLs for the API
480
480
  var TESTNET_API_URL = 'https://api.testnet.1money.network';
481
- var MAINNET_API_URL = 'https://api.1money.network';
481
+ var MAINNET_API_URL = 'https://api.mainnet.1money.network';
482
482
  var LOCAL_API_URL = 'http://localhost:18555';
483
483
  // API version
484
484
  var API_VERSION = 'v1';var API_PREFIX$4 = "/".concat(API_VERSION, "/accounts");
package/lib/index.js CHANGED
@@ -1546,7 +1546,7 @@ var client$1 = {
1546
1546
  axiosStatic: axiosStatic
1547
1547
  };// Base URLs for the API
1548
1548
  var TESTNET_API_URL = 'https://api.testnet.1money.network';
1549
- var MAINNET_API_URL = 'https://api.1money.network';
1549
+ var MAINNET_API_URL = 'https://api.mainnet.1money.network';
1550
1550
  var LOCAL_API_URL = 'http://localhost:18555';
1551
1551
  // API version
1552
1552
  var API_VERSION = 'v1';var API_PREFIX$4 = "/".concat(API_VERSION, "/accounts");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1money/protocol-ts-sdk",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "ts sdk for 1Money protocol network",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
@@ -0,0 +1,205 @@
1
+ ---
2
+ name: 1money-protocol-sdk
3
+ description: >-
4
+ Use when writing or reviewing code that consumes the @1money/protocol-ts-sdk
5
+ package to talk to the 1Money Network blockchain. Covers initializing the
6
+ api() client, the .success()/.error()/.timeout()/.rest() promise-wrapper
7
+ pattern, and the build → sign → submit flow for transactions (payments, token
8
+ issue/mint/burn, authority grants, blacklist/whitelist, pause, metadata,
9
+ bridge, clawback) via TransactionBuilder + createPrivateKeySigner. Trigger
10
+ whenever the user mentions 1Money / 1money / "protocol-ts-sdk", or asks to
11
+ issue/mint/burn/transfer a token, query a nonce/balance/checkpoint/chain id,
12
+ estimate a fee, sign or submit a 1Money transaction, or handle the SDK's
13
+ promise/error pattern — even if they don't name the package. Do NOT use for
14
+ generic EVM/ethers/viem work unrelated to 1Money, or for the 1Money UI
15
+ component / React hooks / Figma skills (different domains).
16
+ ---
17
+
18
+ # Using the @1money/protocol-ts-sdk
19
+
20
+ This skill makes Claude correct and idiomatic when building apps on top of
21
+ `@1money/protocol-ts-sdk` — the TypeScript SDK for the **1Money Network**
22
+ blockchain. The SDK does three things, and almost every task is one of them:
23
+
24
+ 1. **Read chain state** — query nonces, balances, token metadata, checkpoints,
25
+ chain id, transactions, fee estimates. (`api()` client, GET methods.)
26
+ 2. **Write transactions** — build an unsigned tx, sign it, submit it. This is a
27
+ strict three-step pipeline; getting the steps or their order wrong is the
28
+ most common failure.
29
+ 3. **Use helper utilities** — derive token-account addresses, hash, hex-encode.
30
+
31
+ When the user's task is non-trivial (multi-step flows, signing, error handling,
32
+ choosing the right endpoint), **read the relevant reference file** rather than
33
+ guessing signatures — the SDK has specific shapes that are easy to get subtly
34
+ wrong.
35
+
36
+ | You need… | Read |
37
+ | --- | --- |
38
+ | Every read endpoint, its args, and response shape | `references/api-reference.md` |
39
+ | Building + signing + submitting any transaction type | `references/transactions.md` |
40
+ | Promise wrapper, error handling, config, networks, utils | `references/client-and-errors.md` |
41
+
42
+ ## Install
43
+
44
+ ```shell
45
+ npm i -S @1money/protocol-ts-sdk axios viem @ethereumjs/rlp
46
+ ```
47
+
48
+ `axios`, `viem`, and `@ethereumjs/rlp` are **peer dependencies** — the consuming
49
+ app must install them too, or imports fail at runtime. Keep them within the
50
+ ranges in the package's `peerDependencies` (axios ≥1.15 <2, viem ≥2 <3,
51
+ @ethereumjs/rlp ≥10 <11).
52
+
53
+ ## Where to import from (this trips people up)
54
+
55
+ The package root re-exports only: the `api` function, the **signing** layer
56
+ (`TransactionBuilder`, `createPrivateKeySigner`, signer/types), the **utils**
57
+ (`deriveTokenAddress`, `calcTxHash`, `toHex`, …), and `client`.
58
+
59
+ Enums (`AuthorityType`, `AuthorityAction`, `ManageListAction`, `PauseAction`)
60
+ and request/response **types** live under the `/api` subpath, **not** the root.
61
+ The README imports some enums from the root — that's a bug: the root never
62
+ re-exports them, and because enums are runtime *values* (not erasable types) a
63
+ root import resolves to `undefined` (so `AuthorityType.MasterMint` throws) or
64
+ fails to compile. Always import enums from `/api`:
65
+
66
+ ```typescript
67
+ import { api, TransactionBuilder, createPrivateKeySigner } from '@1money/protocol-ts-sdk';
68
+ import { AuthorityType, ManageListAction } from '@1money/protocol-ts-sdk/api';
69
+ ```
70
+
71
+ The only public subpaths are `.`, `/api`, `/client`, and `/utils`. `CHAIN_IDS`
72
+ is **not** re-exported from any of them, so don't import it — get the chain id at
73
+ runtime with `client.chain.getChainId()`.
74
+
75
+ ## Initialize the client
76
+
77
+ ```typescript
78
+ import { api } from '@1money/protocol-ts-sdk';
79
+
80
+ const client = api(); // mainnet (default)
81
+ const testnet = api({ network: 'testnet' }); // 'mainnet' | 'testnet' | 'local'
82
+ const slow = api({ network: 'testnet', timeout: 5000 }); // ms, default 10000
83
+ ```
84
+
85
+ `client` exposes five modules: `accounts`, `checkpoints`, `tokens`,
86
+ `transactions`, `chain`.
87
+
88
+ > **Singleton gotcha:** `api()` configures one shared underlying HTTP client via
89
+ > global config (base URL, timeout). It does **not** create isolated instances —
90
+ > the most recent `api(...)` call wins for *all* references. Don't expect a
91
+ > mainnet client and a testnet client to coexist in the same process; pick one
92
+ > network per process, or re-call `api({network})` before a batch of calls.
93
+
94
+ ## The promise-wrapper pattern (read this before any call)
95
+
96
+ Every API method returns a thenable with handler methods. **You can either chain
97
+ handlers or `await` directly — but be deliberate about which.**
98
+
99
+ ```typescript
100
+ // Chain style — handlers transform the result; errors are HANDLED, not thrown.
101
+ client.checkpoints.getNumber()
102
+ .success(res => console.log(res.number))
103
+ .error(err => console.error(err));
104
+
105
+ // Await style — resolves with the response body on success, THROWS on error.
106
+ try {
107
+ const res = await client.checkpoints.getNumber();
108
+ console.log(res.number);
109
+ } catch (err) {
110
+ console.error(err); // ParsedError: { name, message, status, data, stack }
111
+ }
112
+ ```
113
+
114
+ Key facts that prevent bugs:
115
+
116
+ - The value passed to `.success(cb)` is the **decoded response body directly**
117
+ (e.g. `{ nonce }`, `{ chain_id }`) — there is no `.data` wrapper to unwrap.
118
+ - Available handlers: `.success`, `.failure`, `.error`, `.timeout`, `.login`,
119
+ and `.rest` (a catch-all for the cases you didn't handle). `.timeout` fires
120
+ specifically on the configured timeout.
121
+ - If you attach `.error()`/`.rest()`, awaiting the chain **resolves** with the
122
+ handler's return value instead of throwing. If you attach no error handler and
123
+ `await`, errors **throw**. Pick one model per call site; don't half-mix them.
124
+
125
+ Full semantics and the `.rest(cb, scope)` form are in
126
+ `references/client-and-errors.md`.
127
+
128
+ ## Writing a transaction: build → sign → submit
129
+
130
+ Every state-changing operation follows the **same three steps**. Never hand-roll
131
+ RLP encoding, hashing, or signatures — `TransactionBuilder` does it correctly
132
+ (including low-S enforcement to avoid malleability).
133
+
134
+ ```typescript
135
+ import { api, TransactionBuilder, createPrivateKeySigner } from '@1money/protocol-ts-sdk';
136
+
137
+ const client = api({ network: 'testnet' });
138
+ const sender = '0x9E1E9688A44D058fF181Ed64ddFAFbBE5CC74ff3';
139
+ const privateKey = process.env.ONE_MONEY_PRIVATE_KEY as `0x${string}`; // never hardcode
140
+
141
+ // 1. Fetch the two fields every tx needs: chain_id and the sender's nonce.
142
+ // Awaiting directly returns the response body (and throws on error).
143
+ const { chain_id } = await client.chain.getChainId();
144
+ const { nonce } = await client.accounts.getNonce(sender);
145
+
146
+ // 2. BUILD the unsigned transaction (validates inputs, prepares the digest).
147
+ const prepared = TransactionBuilder.payment({
148
+ chain_id,
149
+ nonce,
150
+ recipient: '0xa128999Be299373D7881f4aDD11510030ad13512',
151
+ value: '1000000000', // ALWAYS a string in the token's base units
152
+ token: '0x2cd8999Be299373D7881f4aDD11510030ad1412F',
153
+ });
154
+
155
+ // 3. SIGN, then build the request body, then SUBMIT to the matching endpoint.
156
+ const signed = await prepared.sign(createPrivateKeySigner(privateKey));
157
+ const { hash } = await client.transactions.payment(signed.toRequest()); // throws on error
158
+
159
+ console.log('tx hash:', hash);
160
+ ```
161
+
162
+ The builder you call and the endpoint you submit to must match. Quick map:
163
+
164
+ | `TransactionBuilder.…` | Submit with `client.…` | Returns |
165
+ | --- | --- | --- |
166
+ | `payment` | `transactions.payment` | `{ hash }` |
167
+ | `tokenIssue` | `tokens.issueToken` | `{ hash, token }` |
168
+ | `tokenMint` | `tokens.mintToken` | `{ hash }` |
169
+ | `tokenBurn` | `tokens.burnToken` | `{ hash }` |
170
+ | `tokenAuthority` | `tokens.grantAuthority` | `{ hash }` |
171
+ | `tokenManageList` | `tokens.manageBlacklist` / `tokens.manageWhitelist` | `{ hash }` |
172
+ | `tokenPause` | `tokens.pauseToken` | `{ hash }` |
173
+ | `tokenMetadata` | `tokens.updateMetadata` | `{ hash }` |
174
+ | `tokenBridgeAndMint` | `tokens.bridgeAndMint` | `{ hash }` |
175
+ | `tokenBurnAndBridge` | `tokens.burnAndBridge` | `{ hash }` |
176
+ | `tokenClawback` | `tokens.clawbackToken` | `{ hash }` |
177
+
178
+ Exact parameter fields for each builder, the enum values they need, the optional
179
+ `memo` field (and how it switches a tx to the V2 envelope), a custom-signer
180
+ pattern (wallets/HSM, when you can't hold the raw key), the alternate **EIP-712
181
+ typed-data payment** path (`preparePaymentTypedTx`, for `eth_signTypedData_v4`
182
+ wallets), and verifying the result are in `references/transactions.md`.
183
+
184
+ ## Non-negotiable conventions
185
+
186
+ These reflect what the SDK actually validates and how the chain expects data —
187
+ violating them throws or silently produces a bad transaction.
188
+
189
+ - **Amounts are decimal strings in base units**, never JS numbers and never
190
+ decimals. 1 token with 18 decimals = `'1000000000000000000'`. The builders
191
+ validate `value` matches `/^\d+$/`.
192
+ - **Addresses must be valid + EIP-55**. Builders validate with viem's
193
+ `isAddress`; a wrongly-checksummed mixed-case address is rejected.
194
+ - **`chain_id` and `nonce` are integers** you fetch fresh per transaction
195
+ (`chain.getChainId`, `accounts.getNonce`). Reusing a stale nonce fails; for
196
+ several txs from one sender, increment locally or re-fetch between them.
197
+ - **Never hardcode or commit a private key.** Load from env/secret store. Prefer
198
+ `createPrivateKeySigner`, or a custom `SignerAdapter` when the key lives in a
199
+ wallet/HSM.
200
+ - **Prefer `TransactionBuilder` over `signMessage`/`encodePayload`.** The latter
201
+ are `@deprecated` legacy helpers; the builder flow is the supported path.
202
+ - **`memo` is optional but not cosmetic.** Every builder accepts `memo?: Memo`
203
+ (`{ type?, format?, data? }`). Passing *any* memo — even `{}` — switches the tx
204
+ to the V2 envelope and changes its signature/tx hash vs. the no-memo V1 form.
205
+ Omit it unless you actually want a memo. Details in `references/transactions.md`.