Skip to content

Commit 307ea11

Browse files
committed
The wonder of their singing, its elusive blend of man and camel
0 parents  commit 307ea11

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+6911
-0
lines changed

.claude/skills/signet-order.md

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# signet-order
2+
3+
Generate TypeScript code for creating and signing Signet orders using @signet/sdk.
4+
5+
## Usage
6+
7+
```
8+
/signet-order [type] [options]
9+
```
10+
11+
**Types:**
12+
- `order` (default) - Create a swap order
13+
- `fill` - Create a fill for an existing order
14+
- `hash` - Compute order hash from existing data
15+
16+
**Options (space-separated after type):**
17+
- `mainnet` or `testnet` - Target network (default: mainnet)
18+
- `multi-input` or `multi-output` - Multiple tokens
19+
- `raw` - Use raw SignedOrder type instead of builder
20+
21+
## Instructions
22+
23+
When invoked, generate TypeScript code for the requested operation. Always:
24+
25+
1. Import from `@signet/sdk` using explicit type imports where appropriate
26+
2. Import viem utilities as needed (`createWalletClient`, `http`, `privateKeyToAccount`)
27+
3. Use the fluent builder API (`UnsignedOrder.new()...`) unless `raw` option is specified
28+
4. Include placeholder addresses with clear comments (e.g., `"0x..." // Your token address`)
29+
5. Use BigInt literals for amounts with human-readable comments (e.g., `1000000n // 1 USDC (6 decimals)`)
30+
6. Set reasonable deadline (1 hour from now by default)
31+
7. Use the appropriate chain config (MAINNET or PARMIGIANA for testnet)
32+
33+
## Examples
34+
35+
### Default: Simple Order
36+
37+
```typescript
38+
import { UnsignedOrder, MAINNET, orderHash } from "@signet/sdk";
39+
import { createWalletClient, http } from "viem";
40+
import { privateKeyToAccount } from "viem/accounts";
41+
import { mainnet } from "viem/chains";
42+
43+
// Configure wallet
44+
const account = privateKeyToAccount("0x..."); // Your private key
45+
const client = createWalletClient({
46+
account,
47+
chain: mainnet,
48+
transport: http("https://eth.llamarpc.com"),
49+
});
50+
51+
// Token addresses
52+
const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
53+
const WETH = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
54+
55+
// Build and sign order
56+
const signedOrder = await UnsignedOrder.new()
57+
.withInput(USDC, 1000_000000n) // 1000 USDC (6 decimals)
58+
.withOutput(
59+
WETH,
60+
500000000000000000n, // 0.5 WETH (18 decimals)
61+
account.address,
62+
MAINNET.rollupChainId
63+
)
64+
.withDeadline(BigInt(Math.floor(Date.now() / 1000) + 3600)) // 1 hour
65+
.withChain({
66+
chainId: MAINNET.rollupChainId,
67+
orderContract: MAINNET.rollupOrders,
68+
})
69+
.sign(client);
70+
71+
// Get order hash for tracking
72+
const hash = orderHash(signedOrder);
73+
console.log("Order hash:", hash);
74+
console.log("Order:", signedOrder);
75+
```
76+
77+
### Fill Example
78+
79+
```typescript
80+
import { UnsignedFill, MAINNET, type Output } from "@signet/sdk";
81+
import { createWalletClient, http } from "viem";
82+
import { privateKeyToAccount } from "viem/accounts";
83+
import { mainnet } from "viem/chains";
84+
85+
const account = privateKeyToAccount("0x..."); // Filler's private key
86+
const client = createWalletClient({
87+
account,
88+
chain: mainnet,
89+
transport: http("https://eth.llamarpc.com"),
90+
});
91+
92+
// Outputs from the order being filled
93+
const orderOutputs: Output[] = [
94+
{
95+
token: "0x...", // Output token address
96+
amount: 500000000000000000n,
97+
recipient: "0x...", // Original order maker
98+
chainId: MAINNET.rollupChainId,
99+
},
100+
];
101+
102+
const signedFill = await UnsignedFill.new()
103+
.withOutputs(orderOutputs)
104+
.withDeadline(BigInt(Math.floor(Date.now() / 1000) + 3600))
105+
.withNonce(BigInt(Date.now())) // Use timestamp as nonce
106+
.withChain({
107+
chainId: MAINNET.rollupChainId,
108+
orderContract: MAINNET.rollupOrders,
109+
})
110+
.sign(client);
111+
112+
console.log("Signed fill:", signedFill);
113+
```
114+
115+
### Hash Computation Example
116+
117+
```typescript
118+
import { orderHash, orderHashPreImage, type SignedOrder } from "@signet/sdk";
119+
120+
// Existing signed order (from API, database, etc.)
121+
const order: SignedOrder = {
122+
permit: {
123+
permit: {
124+
permitted: [{ token: "0x...", amount: 1000000n }],
125+
nonce: 12345n,
126+
deadline: 1700000000n,
127+
},
128+
owner: "0x...",
129+
signature: "0x...",
130+
},
131+
outputs: [
132+
{
133+
token: "0x...",
134+
amount: 500000000000000000n,
135+
recipient: "0x...",
136+
chainId: 519n,
137+
},
138+
],
139+
};
140+
141+
const hash = orderHash(order);
142+
const preImage = orderHashPreImage(order); // 128-byte pre-image
143+
144+
console.log("Order hash:", hash);
145+
console.log("Pre-image:", preImage);
146+
```
147+
148+
### Testnet Example
149+
150+
```typescript
151+
import { UnsignedOrder, PARMIGIANA, orderHash } from "@signet/sdk";
152+
import { createWalletClient, http } from "viem";
153+
import { privateKeyToAccount } from "viem/accounts";
154+
155+
const account = privateKeyToAccount("0x...");
156+
const client = createWalletClient({
157+
account,
158+
chain: {
159+
id: Number(PARMIGIANA.hostChainId),
160+
name: "Parmigiana Host",
161+
nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 },
162+
rpcUrls: { default: { http: ["http://localhost:8545"] } },
163+
},
164+
transport: http("http://localhost:8545"),
165+
});
166+
167+
const signedOrder = await UnsignedOrder.new()
168+
.withInput("0x...", 1000000n)
169+
.withOutput("0x...", 500000000000000000n, account.address, PARMIGIANA.rollupChainId)
170+
.withDeadline(BigInt(Math.floor(Date.now() / 1000) + 3600))
171+
.withChain({
172+
chainId: PARMIGIANA.rollupChainId,
173+
orderContract: PARMIGIANA.rollupOrders,
174+
})
175+
.sign(client);
176+
177+
console.log("Testnet order hash:", orderHash(signedOrder));
178+
```
179+
180+
### Multi-Input/Output Example
181+
182+
```typescript
183+
import { UnsignedOrder, MAINNET, orderHash, type Input, type Output } from "@signet/sdk";
184+
import { createWalletClient, http } from "viem";
185+
import { privateKeyToAccount } from "viem/accounts";
186+
import { mainnet } from "viem/chains";
187+
188+
const account = privateKeyToAccount("0x...");
189+
const client = createWalletClient({
190+
account,
191+
chain: mainnet,
192+
transport: http("https://eth.llamarpc.com"),
193+
});
194+
195+
// Multiple inputs (tokens you're offering)
196+
const inputs: Input[] = [
197+
{ token: "0x...", amount: 1000_000000n }, // 1000 USDC
198+
{ token: "0x...", amount: 500_000000n }, // 500 USDT
199+
];
200+
201+
// Multiple outputs (tokens you want)
202+
const outputs: Output[] = [
203+
{
204+
token: "0x...",
205+
amount: 1000000000000000000n, // 1 WETH
206+
recipient: account.address,
207+
chainId: MAINNET.rollupChainId,
208+
},
209+
{
210+
token: "0x...",
211+
amount: 50000000000000000000n, // 50 LINK
212+
recipient: account.address,
213+
chainId: MAINNET.rollupChainId,
214+
},
215+
];
216+
217+
const signedOrder = await UnsignedOrder.new()
218+
.withInputs(inputs)
219+
.withOutputs(outputs)
220+
.withDeadline(BigInt(Math.floor(Date.now() / 1000) + 3600))
221+
.withChain({
222+
chainId: MAINNET.rollupChainId,
223+
orderContract: MAINNET.rollupOrders,
224+
})
225+
.sign(client);
226+
227+
console.log("Multi-token order:", orderHash(signedOrder));
228+
```
229+
230+
## Response Format
231+
232+
When generating code:
233+
234+
1. Start with a brief explanation of what the code does
235+
2. Provide the complete, runnable TypeScript code
236+
3. Add notes about:
237+
- Required setup (wallet, RPC endpoint)
238+
- Token decimal handling
239+
- How to customize for specific use case

.editorconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
indent_style = space
7+
indent_size = 2
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
11+
[*.md]
12+
trim_trailing_whitespace = false

.github/CODEOWNERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
* @init4tech/engineering
2+
.github/workflows @rswanson

.github/dependabot.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: npm
4+
directory: /
5+
schedule:
6+
interval: weekly
7+
day: monday
8+
open-pull-requests-limit: 10
9+
groups:
10+
dev-dependencies:
11+
patterns:
12+
- "@types/*"
13+
- "eslint*"
14+
- "typescript*"
15+
- "vitest"
16+
- "prettier"
17+
update-types:
18+
- minor
19+
- patch
20+
commit-message:
21+
prefix: "chore(deps):"
22+
23+
- package-ecosystem: github-actions
24+
directory: /
25+
schedule:
26+
interval: weekly
27+
day: monday
28+
commit-message:
29+
prefix: "chore(ci):"

.github/workflows/ci.yml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
lint:
15+
name: Lint & Format
16+
runs-on:
17+
group: init4-runners
18+
steps:
19+
- uses: actions/checkout@v6
20+
- uses: pnpm/action-setup@v4
21+
- uses: actions/setup-node@v4
22+
with:
23+
node-version: 22
24+
cache: pnpm
25+
26+
- run: pnpm install --frozen-lockfile
27+
- run: pnpm format:check
28+
- run: pnpm lint
29+
30+
typecheck:
31+
name: Type Check
32+
runs-on:
33+
group: init4-runners
34+
steps:
35+
- uses: actions/checkout@v6
36+
- uses: pnpm/action-setup@v4
37+
- uses: actions/setup-node@v4
38+
with:
39+
node-version: 22
40+
cache: pnpm
41+
42+
- run: pnpm install --frozen-lockfile
43+
- run: pnpm typecheck
44+
45+
test:
46+
name: Test (Node ${{ matrix.node }})
47+
runs-on:
48+
group: init4-runners
49+
strategy:
50+
fail-fast: false
51+
matrix:
52+
node: [18, 20, 22]
53+
steps:
54+
- uses: actions/checkout@v6
55+
- uses: pnpm/action-setup@v4
56+
- uses: actions/setup-node@v4
57+
with:
58+
node-version: ${{ matrix.node }}
59+
cache: pnpm
60+
61+
- run: pnpm install --frozen-lockfile
62+
- run: pnpm test:run -- --coverage
63+
- uses: codecov/codecov-action@v4
64+
if: matrix.node == 22
65+
with:
66+
token: ${{ secrets.CODECOV_TOKEN }}
67+
fail_ci_if_error: false
68+
69+
build:
70+
name: Build
71+
runs-on:
72+
group: init4-runners
73+
steps:
74+
- uses: actions/checkout@v6
75+
- uses: pnpm/action-setup@v4
76+
- uses: actions/setup-node@v4
77+
with:
78+
node-version: 22
79+
cache: pnpm
80+
81+
- run: pnpm install --frozen-lockfile
82+
- run: pnpm build
83+
84+
- name: Check dist output
85+
run: |
86+
test -f dist/index.js
87+
test -f dist/index.d.ts

0 commit comments

Comments
 (0)