|
| 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 |
0 commit comments