@escro/sdk 0.1.2 → 0.1.4

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/dist/index.cjs CHANGED
@@ -315,6 +315,10 @@ async function buildReleasePaymentTx(params) {
315
315
  import_spl_token.TOKEN_PROGRAM_ID,
316
316
  import_spl_token.ASSOCIATED_TOKEN_PROGRAM_ID
317
317
  );
318
+ const [workerAtaInfo, treasuryAtaInfo] = await connection.getMultipleAccountsInfo([
319
+ workerAta,
320
+ treasuryAta
321
+ ]);
318
322
  const ix = new import_web3.TransactionInstruction({
319
323
  programId: PROGRAM_ID,
320
324
  keys: [
@@ -336,6 +340,16 @@ async function buildReleasePaymentTx(params) {
336
340
  const tx = new import_web3.Transaction();
337
341
  tx.recentBlockhash = blockhash;
338
342
  tx.feePayer = buyer;
343
+ if (!workerAtaInfo) {
344
+ tx.add(
345
+ (0, import_spl_token.createAssociatedTokenAccountInstruction)(buyer, workerAta, worker, mint)
346
+ );
347
+ }
348
+ if (!treasuryAtaInfo) {
349
+ tx.add(
350
+ (0, import_spl_token.createAssociatedTokenAccountInstruction)(buyer, treasuryAta, treasury, mint)
351
+ );
352
+ }
339
353
  tx.add(ix);
340
354
  return tx.serialize({ requireAllSignatures: false }).toString("base64");
341
355
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/api.ts","../src/errors.ts","../src/poll.ts","../src/solana.ts"],"sourcesContent":["export { Escro } from \"./client.js\";\nexport type { EscroOptions, CreateEscrowParams, CreateEscrowResult, SubmitDeliverableParams, RaiseDisputeParams, PollOptions, ListOptions, PaginatedResult } from \"./types.js\";\nexport { EscroError, EscrowNotFoundError, EscrowStateError, EscrowTimeoutError, UnauthorizedError } from \"./errors.js\";\n\n// Re-export the shared types most commonly needed by SDK consumers.\nexport type {\n EscrowAccount,\n EscrowState,\n Network,\n TaskSpec,\n AcceptanceCriterion,\n DeliverableFormat,\n DeliverableType,\n TaskType,\n EscrowErrorCode,\n} from \"@escro/shared\";\n","import { Connection, PublicKey } from \"@solana/web3.js\";\nimport type { EscrowAccount, EscrowState } from \"@escro/shared\";\nimport type {\n CreateEscrowParams,\n CreateEscrowResult,\n EscroOptions,\n ListOptions,\n PaginatedResult,\n PollOptions,\n RaiseDisputeParams,\n SubmitDeliverableParams,\n} from \"./types.js\";\nimport { ApiClient } from \"./api.js\";\nimport { EscrowNotFoundError } from \"./errors.js\";\nimport { pollUntil } from \"./poll.js\";\nimport { buildReleasePaymentTx, fetchPlatformConfig, signAndSend } from \"./solana.js\";\n\nexport class Escro {\n private readonly connection: Connection;\n private readonly api: ApiClient;\n private readonly options: EscroOptions;\n\n constructor(options: EscroOptions) {\n this.options = options;\n this.connection = new Connection(options.rpcUrl, \"confirmed\");\n this.api = new ApiClient(options.apiUrl, options.wallet);\n }\n\n // ── Buyer Bot ────────────────────────────────────────────────────────────────\n\n /**\n * Create a new escrow: registers with the API, signs and submits the\n * on-chain `create_escrow` transaction.\n *\n * @returns `{ escrowId, escrowPda, signature }` — use `escrowPda` for all subsequent calls.\n */\n async createEscrow(params: CreateEscrowParams): Promise<CreateEscrowResult> {\n const { escrowId, escrowPda, unsignedTx } = await this.api.createEscrow(params);\n const signature = await signAndSend(unsignedTx, this.options.wallet, this.connection);\n return { escrowId, escrowPda, signature };\n }\n\n /**\n * Release payment to the worker. Buyer must be the wallet in the constructor.\n * Updates API DB state, then builds and submits the `release_payment` on-chain tx.\n *\n * @returns Solana transaction signature.\n */\n async releasePayment(address: string): Promise<string> {\n // Fetch escrow metadata for worker pubkey + mint\n const escrow = await this.api.getEscrow(address);\n if (!escrow.taker) {\n throw new EscrowNotFoundError(`Escrow ${address} has no assigned worker`);\n }\n\n // Fetch platform config for treasury pubkey + usdc mint\n const { treasury, mint } = await fetchPlatformConfig(this.connection);\n\n // Update DB state (optimistic — on-chain reconciliation runs asynchronously)\n await this.api.releasePaymentDb(address);\n\n // Build, sign, and submit the on-chain instruction\n const unsignedTx = await buildReleasePaymentTx({\n buyer: this.options.wallet.publicKey,\n escrowPda: new PublicKey(address),\n worker: new PublicKey(escrow.taker),\n mint,\n treasury,\n connection: this.connection,\n });\n\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n /**\n * Raise a dispute for an escrow. Either the buyer or the assigned worker\n * may call this. Signs and submits the `raise_dispute` on-chain tx.\n *\n * @returns Solana transaction signature.\n */\n async raiseDispute(address: string, params: RaiseDisputeParams): Promise<string> {\n const { unsignedTx } = await this.api.raiseDispute(address, params);\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n /**\n * Cancel a funded escrow before any worker has claimed it.\n * Buyer must be the wallet in the constructor. Only valid when state is `FUNDED`.\n * Signs and submits the `cancel_escrow` on-chain tx; full USDC refund to buyer.\n *\n * @returns Solana transaction signature.\n */\n async cancelEscrow(address: string): Promise<string> {\n const { unsignedTx } = await this.api.cancelEscrow(address);\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n // ── Worker Bot ───────────────────────────────────────────────────────────────\n\n /**\n * Claim an assigned task. Worker must be the wallet in the constructor.\n * Signs and submits the `claim_task` on-chain tx.\n *\n * @returns Solana transaction signature.\n */\n async claimTask(address: string): Promise<string> {\n const { unsignedTx } = await this.api.claimTask(address);\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n /**\n * Submit a deliverable for oracle evaluation. Worker must be the wallet.\n * Signs and submits the `submit_deliverable` on-chain tx.\n *\n * @returns Solana transaction signature.\n */\n async submitDeliverable(address: string, params: SubmitDeliverableParams): Promise<string> {\n const { unsignedTx } = await this.api.submitDeliverable(address, params);\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n /**\n * List tasks assigned to the wallet's public key.\n * Optionally filter by state(s) and paginate results.\n *\n * If `options.poll` is true, polls with exponential backoff until at least\n * one task is returned.\n *\n * @param state - Filter by one or more states (first state used as API filter).\n * @param options - Polling, pagination (limit/offset).\n */\n async getMyTasks(\n state?: EscrowState[],\n options?: PollOptions & ListOptions,\n ): Promise<PaginatedResult<EscrowAccount>> {\n const assignedTo = this.options.wallet.publicKey.toBase58();\n const params: Parameters<ApiClient[\"listEscrows\"]>[0] = {\n assignedTo,\n ...(state?.[0] != null && { state: state[0] }),\n ...(options?.limit != null && { limit: options.limit }),\n ...(options?.offset != null && { offset: options.offset }),\n };\n\n if (!options?.poll) {\n return this.api.listEscrows(params);\n }\n\n const fetcher = () =>\n this.api\n .listEscrows(params)\n .then((result) => (result.items.length > 0 ? result : null));\n\n return pollUntil(\n assignedTo,\n fetcher,\n (r): r is PaginatedResult<EscrowAccount> => r !== null,\n options.timeoutMs,\n );\n }\n\n // ── Shared ───────────────────────────────────────────────────────────────────\n\n /**\n * Fetch an escrow by its PDA address.\n * If `options.poll` is true, polls with exponential backoff until the escrow\n * appears (useful immediately after a create tx before the API DB syncs).\n */\n async getEscrow(address: string, options?: PollOptions): Promise<EscrowAccount> {\n if (!options?.poll) {\n return this.api.getEscrow(address);\n }\n\n return pollUntil(\n address,\n () =>\n this.api\n .getEscrow(address)\n .catch((e: unknown) => (e instanceof EscrowNotFoundError ? null : Promise.reject(e))),\n (r): r is EscrowAccount => r !== null,\n options.timeoutMs,\n );\n }\n}\n","import nacl from \"tweetnacl\";\nimport bs58 from \"bs58\";\nimport type { Keypair } from \"@solana/web3.js\";\nimport type { EscrowAccount, EscrowState } from \"@escro/shared\";\nimport type {\n CreateEscrowParams,\n ListOptions,\n PaginatedResult,\n RaiseDisputeParams,\n SerializedEscrow,\n SubmitDeliverableParams,\n} from \"./types.js\";\nimport {\n EscroError,\n EscrowNotFoundError,\n EscrowStateError,\n UnauthorizedError,\n} from \"./errors.js\";\n\n// ── Auth header builder ────────────────────────────────────────────────────────\n\nfunction authHeaders(\n wallet: Keypair,\n method: string,\n path: string,\n): Record<string, string> {\n const timestamp = Date.now();\n const message = `escro:${timestamp}:${method}:${path}`;\n const msgBytes = new TextEncoder().encode(message);\n const sigBytes = nacl.sign.detached(msgBytes, wallet.secretKey);\n return {\n \"x-wallet-address\": wallet.publicKey.toBase58(),\n \"x-signature\": bs58.encode(sigBytes),\n \"x-timestamp\": String(timestamp),\n };\n}\n\n// ── Deserialization ────────────────────────────────────────────────────────────\n\nfunction deserialize(raw: SerializedEscrow): EscrowAccount {\n return { ...raw, amount: BigInt(raw.amount) };\n}\n\n// ── Error handling ─────────────────────────────────────────────────────────────\n\nasync function handleError(res: Response, address?: string): Promise<never> {\n const body = (await res.json().catch(() => ({}))) as {\n error?: string;\n code?: string;\n };\n const msg = body.error ?? `HTTP ${res.status}`;\n if (res.status === 404) throw new EscrowNotFoundError(address ?? msg);\n if (res.status === 409) throw new EscrowStateError(msg);\n if (res.status === 401 || res.status === 403) throw new UnauthorizedError(msg);\n throw new EscroError(msg, body.code ?? \"UNKNOWN\");\n}\n\n// ── API client ─────────────────────────────────────────────────────────────────\n\nexport class ApiClient {\n constructor(\n private readonly baseUrl: string,\n private readonly wallet: Keypair,\n ) {}\n\n private url(path: string): string {\n return `${this.baseUrl}${path}`;\n }\n\n /** GET /v1/escrows/:address */\n async getEscrow(address: string): Promise<EscrowAccount> {\n const path = `/v1/escrows/${address}`;\n const res = await fetch(this.url(path));\n if (!res.ok) await handleError(res, address);\n return deserialize((await res.json()) as SerializedEscrow);\n }\n\n /** GET /v1/escrows?assignedTo=...&state=... */\n async listEscrows(params: {\n assignedTo?: string;\n state?: EscrowState;\n limit?: number;\n offset?: number;\n }): Promise<PaginatedResult<EscrowAccount>> {\n const qs = new URLSearchParams();\n if (params.assignedTo) qs.set(\"assignedTo\", params.assignedTo);\n if (params.state) qs.set(\"state\", params.state);\n if (params.limit != null) qs.set(\"limit\", String(params.limit));\n if (params.offset != null) qs.set(\"offset\", String(params.offset));\n\n const path = `/v1/escrows?${qs.toString()}`;\n const res = await fetch(this.url(path));\n if (!res.ok) await handleError(res);\n const body = (await res.json()) as {\n items: SerializedEscrow[];\n total: number;\n limit: number;\n offset: number;\n };\n return {\n items: body.items.map(deserialize),\n total: body.total,\n limit: body.limit,\n offset: body.offset,\n };\n }\n\n /**\n * POST /v1/escrows — create escrow, returns unsigned tx + ids.\n * Requires auth.\n */\n async createEscrow(params: CreateEscrowParams): Promise<{\n escrowId: string;\n escrowPda: string;\n unsignedTx: string;\n }> {\n const path = \"/v1/escrows\";\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: { ...authHeaders(this.wallet, \"POST\", path), \"content-type\": \"application/json\" },\n body: JSON.stringify({\n taskSpec: params.taskSpec,\n amountUsdc: params.amountUsdc,\n deadlineSeconds: params.deadlineSeconds,\n assignedWorker: params.assignedWorker,\n }),\n });\n if (!res.ok) await handleError(res);\n return res.json() as Promise<{ escrowId: string; escrowPda: string; unsignedTx: string }>;\n }\n\n /**\n * POST /v1/escrows/:address/claim — returns unsigned tx.\n * Requires auth (worker).\n */\n async claimTask(address: string): Promise<{ unsignedTx: string }> {\n const path = `/v1/escrows/${address}/claim`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: authHeaders(this.wallet, \"POST\", path),\n });\n if (!res.ok) await handleError(res, address);\n return res.json() as Promise<{ unsignedTx: string }>;\n }\n\n /**\n * POST /v1/escrows/:address/submit — returns unsigned tx.\n * Requires auth (worker).\n */\n async submitDeliverable(\n address: string,\n params: SubmitDeliverableParams,\n ): Promise<{ unsignedTx: string }> {\n const path = `/v1/escrows/${address}/submit`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: { ...authHeaders(this.wallet, \"POST\", path), \"content-type\": \"application/json\" },\n body: JSON.stringify({\n contentHash: params.contentHash,\n proofUri: params.proofUri,\n }),\n });\n if (!res.ok) await handleError(res, address);\n return res.json() as Promise<{ unsignedTx: string }>;\n }\n\n /**\n * POST /v1/escrows/:address/release — DB-only state update.\n * Requires auth (buyer). No on-chain tx returned.\n */\n async releasePaymentDb(address: string): Promise<void> {\n const path = `/v1/escrows/${address}/release`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: authHeaders(this.wallet, \"POST\", path),\n });\n if (!res.ok) await handleError(res, address);\n }\n\n /**\n * POST /v1/escrows/:address/cancel — returns unsigned tx.\n * Requires auth (buyer). Only valid when state is FUNDED.\n */\n async cancelEscrow(address: string): Promise<{ unsignedTx: string }> {\n const path = `/v1/escrows/${address}/cancel`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: authHeaders(this.wallet, \"POST\", path),\n });\n if (!res.ok) await handleError(res, address);\n return res.json() as Promise<{ unsignedTx: string }>;\n }\n\n /**\n * POST /v1/escrows/:address/dispute — returns unsigned tx.\n * Requires auth (buyer or worker).\n */\n async raiseDispute(\n address: string,\n params: RaiseDisputeParams,\n ): Promise<{ unsignedTx: string }> {\n const path = `/v1/escrows/${address}/dispute`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: { ...authHeaders(this.wallet, \"POST\", path), \"content-type\": \"application/json\" },\n body: JSON.stringify({ reason: params.reason, evidence: params.evidence }),\n });\n if (!res.ok) await handleError(res, address);\n return res.json() as Promise<{ unsignedTx: string }>;\n }\n}\n","/** Base class for all errors thrown by the @escro/sdk. */\nexport class EscroError extends Error {\n constructor(\n message: string,\n public readonly code: string = \"ESCRO_ERROR\",\n ) {\n super(message);\n this.name = \"EscroError\";\n }\n}\n\n/** The requested escrow was not found (HTTP 404). */\nexport class EscrowNotFoundError extends EscroError {\n constructor(address: string) {\n super(`Escrow not found: ${address}`, \"ESCROW_NOT_FOUND\");\n this.name = \"EscrowNotFoundError\";\n }\n}\n\n/** The operation is not valid for the escrow's current state (HTTP 409). */\nexport class EscrowStateError extends EscroError {\n constructor(message: string) {\n super(message, \"ESCROW_INVALID_STATE\");\n this.name = \"EscrowStateError\";\n }\n}\n\n/** Polling timed out after 24 hours without reaching the expected state. */\nexport class EscrowTimeoutError extends EscroError {\n constructor(address: string) {\n super(`Polling timed out after 24h for escrow: ${address}`, \"ESCROW_TIMEOUT\");\n this.name = \"EscrowTimeoutError\";\n }\n}\n\n/** The caller is not authorized to perform this action (HTTP 401/403). */\nexport class UnauthorizedError extends EscroError {\n constructor(message = \"Unauthorized\") {\n super(message, \"UNAUTHORIZED\");\n this.name = \"UnauthorizedError\";\n }\n}\n","import { EscrowTimeoutError } from \"./errors.js\";\n\nconst MS_5_MIN = 5 * 60 * 1_000;\nconst MS_30_MIN = 30 * 60 * 1_000;\nconst MS_24_H = 24 * 60 * 60 * 1_000;\n\n/**\n * Returns the next polling interval in ms based on total elapsed time.\n * 0 – 5 min → 15 s\n * 5 – 30 min → 30 s\n * 30 min – ∞ → 60 s\n */\nexport function backoffInterval(elapsedMs: number): number {\n if (elapsedMs < MS_5_MIN) return 15_000;\n if (elapsedMs < MS_30_MIN) return 30_000;\n return 60_000;\n}\n\n/** Resolves after `ms` milliseconds. */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Polls `fetcher` with exponential backoff until `predicate` returns true,\n * then returns the result. Throws {@link EscrowTimeoutError} after 24 hours.\n *\n * @param address - Escrow address used in the timeout error message.\n * @param fetcher - Async function that returns a value or null.\n * @param predicate - Returns true when polling should stop.\n * @param timeoutMs - Maximum total wait time in ms (default: 24 h).\n */\nexport async function pollUntil<T>(\n address: string,\n fetcher: () => Promise<T | null>,\n predicate: (result: T | null) => result is T,\n timeoutMs = MS_24_H,\n): Promise<T> {\n const deadline = Date.now() + timeoutMs;\n\n while (true) {\n const result = await fetcher();\n if (predicate(result)) return result;\n\n const elapsed = Date.now() - (deadline - timeoutMs);\n if (Date.now() >= deadline) {\n throw new EscrowTimeoutError(address);\n }\n\n const interval = backoffInterval(elapsed);\n // Clamp to remaining time so we don't sleep past the deadline\n const remaining = deadline - Date.now();\n await sleep(Math.min(interval, remaining));\n\n if (Date.now() >= deadline) {\n throw new EscrowTimeoutError(address);\n }\n }\n}\n","import { createHash } from \"node:crypto\";\nimport {\n Connection,\n Keypair,\n PublicKey,\n Transaction,\n TransactionInstruction,\n} from \"@solana/web3.js\";\nimport {\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n getAssociatedTokenAddressSync,\n} from \"@solana/spl-token\";\n\n// ── Discriminator helper ───────────────────────────────────────────────────────\n\nfunction disc(name: string): Buffer {\n return Buffer.from(\n createHash(\"sha256\").update(`global:${name}`).digest(),\n ).subarray(0, 8);\n}\n\nconst DISC_RELEASE_PAYMENT = disc(\"release_payment\");\n\n// ── Constants ──────────────────────────────────────────────────────────────────\n\nconst PROGRAM_ID = new PublicKey(\"EjLpJ3obUYk1f2KDensU7UdGBZTxSdxufm7CSnMA3H5C\");\n\n/**\n * PlatformConfig account layout (after 8-byte Anchor discriminator):\n * fee_bps : u16 — offset 8..10\n * oracle_authority : Pubkey — offset 10..42\n * usdc_mint : Pubkey — offset 42..74\n * treasury : Pubkey — offset 74..106\n */\nexport async function fetchPlatformConfig(\n connection: Connection,\n): Promise<{ mint: PublicKey; treasury: PublicKey }> {\n const [pda] = PublicKey.findProgramAddressSync([Buffer.from(\"config\")], PROGRAM_ID);\n const info = await connection.getAccountInfo(pda);\n if (!info) throw new Error(\"PlatformConfig account not found on-chain\");\n return {\n mint: new PublicKey(info.data.slice(42, 74)),\n treasury: new PublicKey(info.data.slice(74, 106)),\n };\n}\n\n// ── Sign and submit ────────────────────────────────────────────────────────────\n\n/**\n * Decode a base64 unsigned transaction, sign it with `wallet`, submit to Solana,\n * and return the transaction signature.\n */\nexport async function signAndSend(\n base64Tx: string,\n wallet: Keypair,\n connection: Connection,\n): Promise<string> {\n const buf = Buffer.from(base64Tx, \"base64\");\n const tx = Transaction.from(buf);\n tx.partialSign(wallet);\n const raw = tx.serialize();\n const signature = await connection.sendRawTransaction(raw, {\n skipPreflight: false,\n });\n await connection.confirmTransaction(signature, \"confirmed\");\n return signature;\n}\n\n// ── release_payment transaction builder ───────────────────────────────────────\n\n/**\n * Build an unsigned `release_payment` transaction.\n * The buyer signs to approve payment to the assigned worker.\n *\n * Account order (matches the on-chain `ReleasePayment` context):\n * 0. buyer — Signer, writable\n * 1. platform_config — read\n * 2. mint — read\n * 3. escrow_account — writable\n * 4. vault — ATA(mint, escrowPda), writable\n * 5. worker_ata — ATA(mint, worker), writable\n * 6. treasury_ata — ATA(mint, treasury), writable\n * 7. worker — read\n * 8. treasury — read\n * 9. token_program — read\n * 10. associated_token_program — read\n */\nexport async function buildReleasePaymentTx(params: {\n buyer: PublicKey;\n escrowPda: PublicKey;\n worker: PublicKey;\n mint: PublicKey;\n treasury: PublicKey;\n connection: Connection;\n}): Promise<string> {\n const { buyer, escrowPda, worker, mint, treasury, connection } = params;\n\n const [platformConfig] = PublicKey.findProgramAddressSync(\n [Buffer.from(\"config\")],\n PROGRAM_ID,\n );\n const vault = getAssociatedTokenAddressSync(\n mint,\n escrowPda,\n true,\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n );\n const workerAta = getAssociatedTokenAddressSync(\n mint,\n worker,\n false,\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n );\n const treasuryAta = getAssociatedTokenAddressSync(\n mint,\n treasury,\n false,\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n );\n\n const ix = new TransactionInstruction({\n programId: PROGRAM_ID,\n keys: [\n { pubkey: buyer, isSigner: true, isWritable: true },\n { pubkey: platformConfig, isSigner: false, isWritable: false },\n { pubkey: mint, isSigner: false, isWritable: false },\n { pubkey: escrowPda, isSigner: false, isWritable: true },\n { pubkey: vault, isSigner: false, isWritable: true },\n { pubkey: workerAta, isSigner: false, isWritable: true },\n { pubkey: treasuryAta, isSigner: false, isWritable: true },\n { pubkey: worker, isSigner: false, isWritable: false },\n { pubkey: treasury, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n ],\n data: DISC_RELEASE_PAYMENT,\n });\n\n const { blockhash } = await connection.getLatestBlockhash(\"confirmed\");\n const tx = new Transaction();\n tx.recentBlockhash = blockhash;\n tx.feePayer = buyer;\n tx.add(ix);\n return tx.serialize({ requireAllSignatures: false }).toString(\"base64\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,eAAsC;;;ACAtC,uBAAiB;AACjB,kBAAiB;;;ACAV,IAAM,aAAN,cAAyB,MAAM;AAAA,EACpC,YACE,SACgB,OAAe,eAC/B;AACA,UAAM,OAAO;AAFG;AAGhB,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,sBAAN,cAAkC,WAAW;AAAA,EAClD,YAAY,SAAiB;AAC3B,UAAM,qBAAqB,OAAO,IAAI,kBAAkB;AACxD,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,mBAAN,cAA+B,WAAW;AAAA,EAC/C,YAAY,SAAiB;AAC3B,UAAM,SAAS,sBAAsB;AACrC,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,qBAAN,cAAiC,WAAW;AAAA,EACjD,YAAY,SAAiB;AAC3B,UAAM,2CAA2C,OAAO,IAAI,gBAAgB;AAC5E,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,oBAAN,cAAgC,WAAW;AAAA,EAChD,YAAY,UAAU,gBAAgB;AACpC,UAAM,SAAS,cAAc;AAC7B,SAAK,OAAO;AAAA,EACd;AACF;;;ADpBA,SAAS,YACP,QACA,QACA,MACwB;AACxB,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,UAAU,SAAS,SAAS,IAAI,MAAM,IAAI,IAAI;AACpD,QAAM,WAAW,IAAI,YAAY,EAAE,OAAO,OAAO;AACjD,QAAM,WAAW,iBAAAC,QAAK,KAAK,SAAS,UAAU,OAAO,SAAS;AAC9D,SAAO;AAAA,IACL,oBAAoB,OAAO,UAAU,SAAS;AAAA,IAC9C,eAAe,YAAAC,QAAK,OAAO,QAAQ;AAAA,IACnC,eAAe,OAAO,SAAS;AAAA,EACjC;AACF;AAIA,SAAS,YAAY,KAAsC;AACzD,SAAO,EAAE,GAAG,KAAK,QAAQ,OAAO,IAAI,MAAM,EAAE;AAC9C;AAIA,eAAe,YAAY,KAAe,SAAkC;AAC1E,QAAM,OAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAI/C,QAAM,MAAM,KAAK,SAAS,QAAQ,IAAI,MAAM;AAC5C,MAAI,IAAI,WAAW,IAAK,OAAM,IAAI,oBAAoB,WAAW,GAAG;AACpE,MAAI,IAAI,WAAW,IAAK,OAAM,IAAI,iBAAiB,GAAG;AACtD,MAAI,IAAI,WAAW,OAAO,IAAI,WAAW,IAAK,OAAM,IAAI,kBAAkB,GAAG;AAC7E,QAAM,IAAI,WAAW,KAAK,KAAK,QAAQ,SAAS;AAClD;AAIO,IAAM,YAAN,MAAgB;AAAA,EACrB,YACmB,SACA,QACjB;AAFiB;AACA;AAAA,EAChB;AAAA,EAEK,IAAI,MAAsB;AAChC,WAAO,GAAG,KAAK,OAAO,GAAG,IAAI;AAAA,EAC/B;AAAA;AAAA,EAGA,MAAM,UAAU,SAAyC;AACvD,UAAM,OAAO,eAAe,OAAO;AACnC,UAAM,MAAM,MAAM,MAAM,KAAK,IAAI,IAAI,CAAC;AACtC,QAAI,CAAC,IAAI,GAAI,OAAM,YAAY,KAAK,OAAO;AAC3C,WAAO,YAAa,MAAM,IAAI,KAAK,CAAsB;AAAA,EAC3D;AAAA;AAAA,EAGA,MAAM,YAAY,QAK0B;AAC1C,UAAM,KAAK,IAAI,gBAAgB;AAC/B,QAAI,OAAO,WAAY,IAAG,IAAI,cAAc,OAAO,UAAU;AAC7D,QAAI,OAAO,MAAO,IAAG,IAAI,SAAS,OAAO,KAAK;AAC9C,QAAI,OAAO,SAAS,KAAM,IAAG,IAAI,SAAS,OAAO,OAAO,KAAK,CAAC;AAC9D,QAAI,OAAO,UAAU,KAAM,IAAG,IAAI,UAAU,OAAO,OAAO,MAAM,CAAC;AAEjE,UAAM,OAAO,eAAe,GAAG,SAAS,CAAC;AACzC,UAAM,MAAM,MAAM,MAAM,KAAK,IAAI,IAAI,CAAC;AACtC,QAAI,CAAC,IAAI,GAAI,OAAM,YAAY,GAAG;AAClC,UAAM,OAAQ,MAAM,IAAI,KAAK;AAM7B,WAAO;AAAA,MACL,OAAO,KAAK,MAAM,IAAI,WAAW;AAAA,MACjC,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAAa,QAIhB;AACD,UAAM,OAAO;AACb,UAAM,MAAM,MAAM,MAAM,KAAK,IAAI,IAAI,GAAG;AAAA,MACtC,QAAQ;AAAA,MACR,SAAS,EAAE,GAAG,YAAY,KAAK,QAAQ,QAAQ,IAAI,GAAG,gBAAgB,mBAAmB;AAAA,MACzF,MAAM,KAAK,UAAU;AAAA,QACnB,UAAU,OAAO;AAAA,QACjB,YAAY,OAAO;AAAA,QACnB,iBAAiB,OAAO;AAAA,QACxB,gBAAgB,OAAO;AAAA,MACzB,CAAC;AAAA,IACH,CAAC;AACD,QAAI,CAAC,IAAI,GAAI,OAAM,YAAY,GAAG;AAClC,WAAO,IAAI,KAAK;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAU,SAAkD;AAChE,UAAM,OAAO,eAAe,OAAO;AACnC,UAAM,MAAM,MAAM,MAAM,KAAK,IAAI,IAAI,GAAG;AAAA,MACtC,QAAQ;AAAA,MACR,SAAS,YAAY,KAAK,QAAQ,QAAQ,IAAI;AAAA,IAChD,CAAC;AACD,QAAI,CAAC,IAAI,GAAI,OAAM,YAAY,KAAK,OAAO;AAC3C,WAAO,IAAI,KAAK;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,kBACJ,SACA,QACiC;AACjC,UAAM,OAAO,eAAe,OAAO;AACnC,UAAM,MAAM,MAAM,MAAM,KAAK,IAAI,IAAI,GAAG;AAAA,MACtC,QAAQ;AAAA,MACR,SAAS,EAAE,GAAG,YAAY,KAAK,QAAQ,QAAQ,IAAI,GAAG,gBAAgB,mBAAmB;AAAA,MACzF,MAAM,KAAK,UAAU;AAAA,QACnB,aAAa,OAAO;AAAA,QACpB,UAAU,OAAO;AAAA,MACnB,CAAC;AAAA,IACH,CAAC;AACD,QAAI,CAAC,IAAI,GAAI,OAAM,YAAY,KAAK,OAAO;AAC3C,WAAO,IAAI,KAAK;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,iBAAiB,SAAgC;AACrD,UAAM,OAAO,eAAe,OAAO;AACnC,UAAM,MAAM,MAAM,MAAM,KAAK,IAAI,IAAI,GAAG;AAAA,MACtC,QAAQ;AAAA,MACR,SAAS,YAAY,KAAK,QAAQ,QAAQ,IAAI;AAAA,IAChD,CAAC;AACD,QAAI,CAAC,IAAI,GAAI,OAAM,YAAY,KAAK,OAAO;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAAa,SAAkD;AACnE,UAAM,OAAO,eAAe,OAAO;AACnC,UAAM,MAAM,MAAM,MAAM,KAAK,IAAI,IAAI,GAAG;AAAA,MACtC,QAAQ;AAAA,MACR,SAAS,YAAY,KAAK,QAAQ,QAAQ,IAAI;AAAA,IAChD,CAAC;AACD,QAAI,CAAC,IAAI,GAAI,OAAM,YAAY,KAAK,OAAO;AAC3C,WAAO,IAAI,KAAK;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aACJ,SACA,QACiC;AACjC,UAAM,OAAO,eAAe,OAAO;AACnC,UAAM,MAAM,MAAM,MAAM,KAAK,IAAI,IAAI,GAAG;AAAA,MACtC,QAAQ;AAAA,MACR,SAAS,EAAE,GAAG,YAAY,KAAK,QAAQ,QAAQ,IAAI,GAAG,gBAAgB,mBAAmB;AAAA,MACzF,MAAM,KAAK,UAAU,EAAE,QAAQ,OAAO,QAAQ,UAAU,OAAO,SAAS,CAAC;AAAA,IAC3E,CAAC;AACD,QAAI,CAAC,IAAI,GAAI,OAAM,YAAY,KAAK,OAAO;AAC3C,WAAO,IAAI,KAAK;AAAA,EAClB;AACF;;;AEhNA,IAAM,WAAW,IAAI,KAAK;AAC1B,IAAM,YAAY,KAAK,KAAK;AAC5B,IAAM,UAAU,KAAK,KAAK,KAAK;AAQxB,SAAS,gBAAgB,WAA2B;AACzD,MAAI,YAAY,SAAU,QAAO;AACjC,MAAI,YAAY,UAAW,QAAO;AAClC,SAAO;AACT;AAGA,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAWA,eAAsB,UACpB,SACA,SACA,WACA,YAAY,SACA;AACZ,QAAM,WAAW,KAAK,IAAI,IAAI;AAE9B,SAAO,MAAM;AACX,UAAM,SAAS,MAAM,QAAQ;AAC7B,QAAI,UAAU,MAAM,EAAG,QAAO;AAE9B,UAAM,UAAU,KAAK,IAAI,KAAK,WAAW;AACzC,QAAI,KAAK,IAAI,KAAK,UAAU;AAC1B,YAAM,IAAI,mBAAmB,OAAO;AAAA,IACtC;AAEA,UAAM,WAAW,gBAAgB,OAAO;AAExC,UAAM,YAAY,WAAW,KAAK,IAAI;AACtC,UAAM,MAAM,KAAK,IAAI,UAAU,SAAS,CAAC;AAEzC,QAAI,KAAK,IAAI,KAAK,UAAU;AAC1B,YAAM,IAAI,mBAAmB,OAAO;AAAA,IACtC;AAAA,EACF;AACF;;;AC1DA,yBAA2B;AAC3B,kBAMO;AACP,uBAIO;AAIP,SAAS,KAAK,MAAsB;AAClC,SAAO,OAAO;AAAA,QACZ,+BAAW,QAAQ,EAAE,OAAO,UAAU,IAAI,EAAE,EAAE,OAAO;AAAA,EACvD,EAAE,SAAS,GAAG,CAAC;AACjB;AAEA,IAAM,uBAAuB,KAAK,iBAAiB;AAInD,IAAM,aAAa,IAAI,sBAAU,8CAA8C;AAS/E,eAAsB,oBACpB,YACmD;AACnD,QAAM,CAAC,GAAG,IAAI,sBAAU,uBAAuB,CAAC,OAAO,KAAK,QAAQ,CAAC,GAAG,UAAU;AAClF,QAAM,OAAO,MAAM,WAAW,eAAe,GAAG;AAChD,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,2CAA2C;AACtE,SAAO;AAAA,IACL,MAAM,IAAI,sBAAU,KAAK,KAAK,MAAM,IAAI,EAAE,CAAC;AAAA,IAC3C,UAAU,IAAI,sBAAU,KAAK,KAAK,MAAM,IAAI,GAAG,CAAC;AAAA,EAClD;AACF;AAQA,eAAsB,YACpB,UACA,QACA,YACiB;AACjB,QAAM,MAAM,OAAO,KAAK,UAAU,QAAQ;AAC1C,QAAM,KAAK,wBAAY,KAAK,GAAG;AAC/B,KAAG,YAAY,MAAM;AACrB,QAAM,MAAM,GAAG,UAAU;AACzB,QAAM,YAAY,MAAM,WAAW,mBAAmB,KAAK;AAAA,IACzD,eAAe;AAAA,EACjB,CAAC;AACD,QAAM,WAAW,mBAAmB,WAAW,WAAW;AAC1D,SAAO;AACT;AAqBA,eAAsB,sBAAsB,QAOxB;AAClB,QAAM,EAAE,OAAO,WAAW,QAAQ,MAAM,UAAU,WAAW,IAAI;AAEjE,QAAM,CAAC,cAAc,IAAI,sBAAU;AAAA,IACjC,CAAC,OAAO,KAAK,QAAQ,CAAC;AAAA,IACtB;AAAA,EACF;AACA,QAAM,YAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,gBAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,kBAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,KAAK,IAAI,mCAAuB;AAAA,IACpC,WAAW;AAAA,IACX,MAAM;AAAA,MACJ,EAAE,QAAQ,OAAO,UAAU,MAAM,YAAY,KAAK;AAAA,MAClD,EAAE,QAAQ,gBAAgB,UAAU,OAAO,YAAY,MAAM;AAAA,MAC7D,EAAE,QAAQ,MAAM,UAAU,OAAO,YAAY,MAAM;AAAA,MACnD,EAAE,QAAQ,WAAW,UAAU,OAAO,YAAY,KAAK;AAAA,MACvD,EAAE,QAAQ,OAAO,UAAU,OAAO,YAAY,KAAK;AAAA,MACnD,EAAE,QAAQ,WAAW,UAAU,OAAO,YAAY,KAAK;AAAA,MACvD,EAAE,QAAQ,aAAa,UAAU,OAAO,YAAY,KAAK;AAAA,MACzD,EAAE,QAAQ,QAAQ,UAAU,OAAO,YAAY,MAAM;AAAA,MACrD,EAAE,QAAQ,UAAU,UAAU,OAAO,YAAY,MAAM;AAAA,MACvD,EAAE,QAAQ,mCAAkB,UAAU,OAAO,YAAY,MAAM;AAAA,MAC/D,EAAE,QAAQ,8CAA6B,UAAU,OAAO,YAAY,MAAM;AAAA,IAC5E;AAAA,IACA,MAAM;AAAA,EACR,CAAC;AAED,QAAM,EAAE,UAAU,IAAI,MAAM,WAAW,mBAAmB,WAAW;AACrE,QAAM,KAAK,IAAI,wBAAY;AAC3B,KAAG,kBAAkB;AACrB,KAAG,WAAW;AACd,KAAG,IAAI,EAAE;AACT,SAAO,GAAG,UAAU,EAAE,sBAAsB,MAAM,CAAC,EAAE,SAAS,QAAQ;AACxE;;;AJnIO,IAAM,QAAN,MAAY;AAAA,EAKjB,YAAY,SAAuB;AAJnC,wBAAiB;AACjB,wBAAiB;AACjB,wBAAiB;AAGf,SAAK,UAAU;AACf,SAAK,aAAa,IAAI,wBAAW,QAAQ,QAAQ,WAAW;AAC5D,SAAK,MAAM,IAAI,UAAU,QAAQ,QAAQ,QAAQ,MAAM;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,aAAa,QAAyD;AAC1E,UAAM,EAAE,UAAU,WAAW,WAAW,IAAI,MAAM,KAAK,IAAI,aAAa,MAAM;AAC9E,UAAM,YAAY,MAAM,YAAY,YAAY,KAAK,QAAQ,QAAQ,KAAK,UAAU;AACpF,WAAO,EAAE,UAAU,WAAW,UAAU;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,eAAe,SAAkC;AAErD,UAAM,SAAS,MAAM,KAAK,IAAI,UAAU,OAAO;AAC/C,QAAI,CAAC,OAAO,OAAO;AACjB,YAAM,IAAI,oBAAoB,UAAU,OAAO,yBAAyB;AAAA,IAC1E;AAGA,UAAM,EAAE,UAAU,KAAK,IAAI,MAAM,oBAAoB,KAAK,UAAU;AAGpE,UAAM,KAAK,IAAI,iBAAiB,OAAO;AAGvC,UAAM,aAAa,MAAM,sBAAsB;AAAA,MAC7C,OAAO,KAAK,QAAQ,OAAO;AAAA,MAC3B,WAAW,IAAI,uBAAU,OAAO;AAAA,MAChC,QAAQ,IAAI,uBAAU,OAAO,KAAK;AAAA,MAClC;AAAA,MACA;AAAA,MACA,YAAY,KAAK;AAAA,IACnB,CAAC;AAED,WAAO,YAAY,YAAY,KAAK,QAAQ,QAAQ,KAAK,UAAU;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,aAAa,SAAiB,QAA6C;AAC/E,UAAM,EAAE,WAAW,IAAI,MAAM,KAAK,IAAI,aAAa,SAAS,MAAM;AAClE,WAAO,YAAY,YAAY,KAAK,QAAQ,QAAQ,KAAK,UAAU;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,aAAa,SAAkC;AACnD,UAAM,EAAE,WAAW,IAAI,MAAM,KAAK,IAAI,aAAa,OAAO;AAC1D,WAAO,YAAY,YAAY,KAAK,QAAQ,QAAQ,KAAK,UAAU;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,UAAU,SAAkC;AAChD,UAAM,EAAE,WAAW,IAAI,MAAM,KAAK,IAAI,UAAU,OAAO;AACvD,WAAO,YAAY,YAAY,KAAK,QAAQ,QAAQ,KAAK,UAAU;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,kBAAkB,SAAiB,QAAkD;AACzF,UAAM,EAAE,WAAW,IAAI,MAAM,KAAK,IAAI,kBAAkB,SAAS,MAAM;AACvE,WAAO,YAAY,YAAY,KAAK,QAAQ,QAAQ,KAAK,UAAU;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,WACJ,OACA,SACyC;AACzC,UAAM,aAAa,KAAK,QAAQ,OAAO,UAAU,SAAS;AAC1D,UAAM,SAAkD;AAAA,MACtD;AAAA,MACA,GAAI,QAAQ,CAAC,KAAK,QAAQ,EAAE,OAAO,MAAM,CAAC,EAAE;AAAA,MAC5C,GAAI,SAAS,SAAS,QAAQ,EAAE,OAAO,QAAQ,MAAM;AAAA,MACrD,GAAI,SAAS,UAAU,QAAQ,EAAE,QAAQ,QAAQ,OAAO;AAAA,IAC1D;AAEA,QAAI,CAAC,SAAS,MAAM;AAClB,aAAO,KAAK,IAAI,YAAY,MAAM;AAAA,IACpC;AAEA,UAAM,UAAU,MACd,KAAK,IACF,YAAY,MAAM,EAClB,KAAK,CAAC,WAAY,OAAO,MAAM,SAAS,IAAI,SAAS,IAAK;AAE/D,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,CAAC,MAA2C,MAAM;AAAA,MAClD,QAAQ;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,UAAU,SAAiB,SAA+C;AAC9E,QAAI,CAAC,SAAS,MAAM;AAClB,aAAO,KAAK,IAAI,UAAU,OAAO;AAAA,IACnC;AAEA,WAAO;AAAA,MACL;AAAA,MACA,MACE,KAAK,IACF,UAAU,OAAO,EACjB,MAAM,CAAC,MAAgB,aAAa,sBAAsB,OAAO,QAAQ,OAAO,CAAC,CAAE;AAAA,MACxF,CAAC,MAA0B,MAAM;AAAA,MACjC,QAAQ;AAAA,IACV;AAAA,EACF;AACF;","names":["import_web3","nacl","bs58"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/api.ts","../src/errors.ts","../src/poll.ts","../src/solana.ts"],"sourcesContent":["export { Escro } from \"./client.js\";\nexport type { EscroOptions, CreateEscrowParams, CreateEscrowResult, SubmitDeliverableParams, RaiseDisputeParams, PollOptions, ListOptions, PaginatedResult } from \"./types.js\";\nexport { EscroError, EscrowNotFoundError, EscrowStateError, EscrowTimeoutError, UnauthorizedError } from \"./errors.js\";\n\n// Re-export the shared types most commonly needed by SDK consumers.\nexport type {\n EscrowAccount,\n EscrowState,\n Network,\n TaskSpec,\n AcceptanceCriterion,\n DeliverableFormat,\n DeliverableType,\n TaskType,\n EscrowErrorCode,\n} from \"@escro/shared\";\n","import { Connection, PublicKey } from \"@solana/web3.js\";\nimport type { EscrowAccount, EscrowState } from \"@escro/shared\";\nimport type {\n CreateEscrowParams,\n CreateEscrowResult,\n EscroOptions,\n ListOptions,\n PaginatedResult,\n PollOptions,\n RaiseDisputeParams,\n SubmitDeliverableParams,\n} from \"./types.js\";\nimport { ApiClient } from \"./api.js\";\nimport { EscrowNotFoundError } from \"./errors.js\";\nimport { pollUntil } from \"./poll.js\";\nimport { buildReleasePaymentTx, fetchPlatformConfig, signAndSend } from \"./solana.js\";\n\nexport class Escro {\n private readonly connection: Connection;\n private readonly api: ApiClient;\n private readonly options: EscroOptions;\n\n constructor(options: EscroOptions) {\n this.options = options;\n this.connection = new Connection(options.rpcUrl, \"confirmed\");\n this.api = new ApiClient(options.apiUrl, options.wallet);\n }\n\n // ── Buyer Bot ────────────────────────────────────────────────────────────────\n\n /**\n * Create a new escrow: registers with the API, signs and submits the\n * on-chain `create_escrow` transaction.\n *\n * @returns `{ escrowId, escrowPda, signature }` — use `escrowPda` for all subsequent calls.\n */\n async createEscrow(params: CreateEscrowParams): Promise<CreateEscrowResult> {\n const { escrowId, escrowPda, unsignedTx } = await this.api.createEscrow(params);\n const signature = await signAndSend(unsignedTx, this.options.wallet, this.connection);\n return { escrowId, escrowPda, signature };\n }\n\n /**\n * Release payment to the worker. Buyer must be the wallet in the constructor.\n * Updates API DB state, then builds and submits the `release_payment` on-chain tx.\n *\n * @returns Solana transaction signature.\n */\n async releasePayment(address: string): Promise<string> {\n // Fetch escrow metadata for worker pubkey + mint\n const escrow = await this.api.getEscrow(address);\n if (!escrow.taker) {\n throw new EscrowNotFoundError(`Escrow ${address} has no assigned worker`);\n }\n\n // Fetch platform config for treasury pubkey + usdc mint\n const { treasury, mint } = await fetchPlatformConfig(this.connection);\n\n // Update DB state (optimistic — on-chain reconciliation runs asynchronously)\n await this.api.releasePaymentDb(address);\n\n // Build, sign, and submit the on-chain instruction\n const unsignedTx = await buildReleasePaymentTx({\n buyer: this.options.wallet.publicKey,\n escrowPda: new PublicKey(address),\n worker: new PublicKey(escrow.taker),\n mint,\n treasury,\n connection: this.connection,\n });\n\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n /**\n * Raise a dispute for an escrow. Either the buyer or the assigned worker\n * may call this. Signs and submits the `raise_dispute` on-chain tx.\n *\n * @returns Solana transaction signature.\n */\n async raiseDispute(address: string, params: RaiseDisputeParams): Promise<string> {\n const { unsignedTx } = await this.api.raiseDispute(address, params);\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n /**\n * Cancel a funded escrow before any worker has claimed it.\n * Buyer must be the wallet in the constructor. Only valid when state is `FUNDED`.\n * Signs and submits the `cancel_escrow` on-chain tx; full USDC refund to buyer.\n *\n * @returns Solana transaction signature.\n */\n async cancelEscrow(address: string): Promise<string> {\n const { unsignedTx } = await this.api.cancelEscrow(address);\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n // ── Worker Bot ───────────────────────────────────────────────────────────────\n\n /**\n * Claim an assigned task. Worker must be the wallet in the constructor.\n * Signs and submits the `claim_task` on-chain tx.\n *\n * @returns Solana transaction signature.\n */\n async claimTask(address: string): Promise<string> {\n const { unsignedTx } = await this.api.claimTask(address);\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n /**\n * Submit a deliverable for oracle evaluation. Worker must be the wallet.\n * Signs and submits the `submit_deliverable` on-chain tx.\n *\n * @returns Solana transaction signature.\n */\n async submitDeliverable(address: string, params: SubmitDeliverableParams): Promise<string> {\n const { unsignedTx } = await this.api.submitDeliverable(address, params);\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n /**\n * List tasks assigned to the wallet's public key.\n * Optionally filter by state(s) and paginate results.\n *\n * If `options.poll` is true, polls with exponential backoff until at least\n * one task is returned.\n *\n * @param state - Filter by one or more states (first state used as API filter).\n * @param options - Polling, pagination (limit/offset).\n */\n async getMyTasks(\n state?: EscrowState[],\n options?: PollOptions & ListOptions,\n ): Promise<PaginatedResult<EscrowAccount>> {\n const assignedTo = this.options.wallet.publicKey.toBase58();\n const params: Parameters<ApiClient[\"listEscrows\"]>[0] = {\n assignedTo,\n ...(state?.[0] != null && { state: state[0] }),\n ...(options?.limit != null && { limit: options.limit }),\n ...(options?.offset != null && { offset: options.offset }),\n };\n\n if (!options?.poll) {\n return this.api.listEscrows(params);\n }\n\n const fetcher = () =>\n this.api\n .listEscrows(params)\n .then((result) => (result.items.length > 0 ? result : null));\n\n return pollUntil(\n assignedTo,\n fetcher,\n (r): r is PaginatedResult<EscrowAccount> => r !== null,\n options.timeoutMs,\n );\n }\n\n // ── Shared ───────────────────────────────────────────────────────────────────\n\n /**\n * Fetch an escrow by its PDA address.\n * If `options.poll` is true, polls with exponential backoff until the escrow\n * appears (useful immediately after a create tx before the API DB syncs).\n */\n async getEscrow(address: string, options?: PollOptions): Promise<EscrowAccount> {\n if (!options?.poll) {\n return this.api.getEscrow(address);\n }\n\n return pollUntil(\n address,\n () =>\n this.api\n .getEscrow(address)\n .catch((e: unknown) => (e instanceof EscrowNotFoundError ? null : Promise.reject(e))),\n (r): r is EscrowAccount => r !== null,\n options.timeoutMs,\n );\n }\n}\n","import nacl from \"tweetnacl\";\nimport bs58 from \"bs58\";\nimport type { Keypair } from \"@solana/web3.js\";\nimport type { EscrowAccount, EscrowState } from \"@escro/shared\";\nimport type {\n CreateEscrowParams,\n ListOptions,\n PaginatedResult,\n RaiseDisputeParams,\n SerializedEscrow,\n SubmitDeliverableParams,\n} from \"./types.js\";\nimport {\n EscroError,\n EscrowNotFoundError,\n EscrowStateError,\n UnauthorizedError,\n} from \"./errors.js\";\n\n// ── Auth header builder ────────────────────────────────────────────────────────\n\nfunction authHeaders(\n wallet: Keypair,\n method: string,\n path: string,\n): Record<string, string> {\n const timestamp = Date.now();\n const message = `escro:${timestamp}:${method}:${path}`;\n const msgBytes = new TextEncoder().encode(message);\n const sigBytes = nacl.sign.detached(msgBytes, wallet.secretKey);\n return {\n \"x-wallet-address\": wallet.publicKey.toBase58(),\n \"x-signature\": bs58.encode(sigBytes),\n \"x-timestamp\": String(timestamp),\n };\n}\n\n// ── Deserialization ────────────────────────────────────────────────────────────\n\nfunction deserialize(raw: SerializedEscrow): EscrowAccount {\n return { ...raw, amount: BigInt(raw.amount) };\n}\n\n// ── Error handling ─────────────────────────────────────────────────────────────\n\nasync function handleError(res: Response, address?: string): Promise<never> {\n const body = (await res.json().catch(() => ({}))) as {\n error?: string;\n code?: string;\n };\n const msg = body.error ?? `HTTP ${res.status}`;\n if (res.status === 404) throw new EscrowNotFoundError(address ?? msg);\n if (res.status === 409) throw new EscrowStateError(msg);\n if (res.status === 401 || res.status === 403) throw new UnauthorizedError(msg);\n throw new EscroError(msg, body.code ?? \"UNKNOWN\");\n}\n\n// ── API client ─────────────────────────────────────────────────────────────────\n\nexport class ApiClient {\n constructor(\n private readonly baseUrl: string,\n private readonly wallet: Keypair,\n ) {}\n\n private url(path: string): string {\n return `${this.baseUrl}${path}`;\n }\n\n /** GET /v1/escrows/:address */\n async getEscrow(address: string): Promise<EscrowAccount> {\n const path = `/v1/escrows/${address}`;\n const res = await fetch(this.url(path));\n if (!res.ok) await handleError(res, address);\n return deserialize((await res.json()) as SerializedEscrow);\n }\n\n /** GET /v1/escrows?assignedTo=...&state=... */\n async listEscrows(params: {\n assignedTo?: string;\n state?: EscrowState;\n limit?: number;\n offset?: number;\n }): Promise<PaginatedResult<EscrowAccount>> {\n const qs = new URLSearchParams();\n if (params.assignedTo) qs.set(\"assignedTo\", params.assignedTo);\n if (params.state) qs.set(\"state\", params.state);\n if (params.limit != null) qs.set(\"limit\", String(params.limit));\n if (params.offset != null) qs.set(\"offset\", String(params.offset));\n\n const path = `/v1/escrows?${qs.toString()}`;\n const res = await fetch(this.url(path));\n if (!res.ok) await handleError(res);\n const body = (await res.json()) as {\n items: SerializedEscrow[];\n total: number;\n limit: number;\n offset: number;\n };\n return {\n items: body.items.map(deserialize),\n total: body.total,\n limit: body.limit,\n offset: body.offset,\n };\n }\n\n /**\n * POST /v1/escrows — create escrow, returns unsigned tx + ids.\n * Requires auth.\n */\n async createEscrow(params: CreateEscrowParams): Promise<{\n escrowId: string;\n escrowPda: string;\n unsignedTx: string;\n }> {\n const path = \"/v1/escrows\";\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: { ...authHeaders(this.wallet, \"POST\", path), \"content-type\": \"application/json\" },\n body: JSON.stringify({\n taskSpec: params.taskSpec,\n amountUsdc: params.amountUsdc,\n deadlineSeconds: params.deadlineSeconds,\n assignedWorker: params.assignedWorker,\n }),\n });\n if (!res.ok) await handleError(res);\n return res.json() as Promise<{ escrowId: string; escrowPda: string; unsignedTx: string }>;\n }\n\n /**\n * POST /v1/escrows/:address/claim — returns unsigned tx.\n * Requires auth (worker).\n */\n async claimTask(address: string): Promise<{ unsignedTx: string }> {\n const path = `/v1/escrows/${address}/claim`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: authHeaders(this.wallet, \"POST\", path),\n });\n if (!res.ok) await handleError(res, address);\n return res.json() as Promise<{ unsignedTx: string }>;\n }\n\n /**\n * POST /v1/escrows/:address/submit — returns unsigned tx.\n * Requires auth (worker).\n */\n async submitDeliverable(\n address: string,\n params: SubmitDeliverableParams,\n ): Promise<{ unsignedTx: string }> {\n const path = `/v1/escrows/${address}/submit`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: { ...authHeaders(this.wallet, \"POST\", path), \"content-type\": \"application/json\" },\n body: JSON.stringify({\n contentHash: params.contentHash,\n proofUri: params.proofUri,\n }),\n });\n if (!res.ok) await handleError(res, address);\n return res.json() as Promise<{ unsignedTx: string }>;\n }\n\n /**\n * POST /v1/escrows/:address/release — DB-only state update.\n * Requires auth (buyer). No on-chain tx returned.\n */\n async releasePaymentDb(address: string): Promise<void> {\n const path = `/v1/escrows/${address}/release`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: authHeaders(this.wallet, \"POST\", path),\n });\n if (!res.ok) await handleError(res, address);\n }\n\n /**\n * POST /v1/escrows/:address/cancel — returns unsigned tx.\n * Requires auth (buyer). Only valid when state is FUNDED.\n */\n async cancelEscrow(address: string): Promise<{ unsignedTx: string }> {\n const path = `/v1/escrows/${address}/cancel`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: authHeaders(this.wallet, \"POST\", path),\n });\n if (!res.ok) await handleError(res, address);\n return res.json() as Promise<{ unsignedTx: string }>;\n }\n\n /**\n * POST /v1/escrows/:address/dispute — returns unsigned tx.\n * Requires auth (buyer or worker).\n */\n async raiseDispute(\n address: string,\n params: RaiseDisputeParams,\n ): Promise<{ unsignedTx: string }> {\n const path = `/v1/escrows/${address}/dispute`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: { ...authHeaders(this.wallet, \"POST\", path), \"content-type\": \"application/json\" },\n body: JSON.stringify({ reason: params.reason, evidence: params.evidence }),\n });\n if (!res.ok) await handleError(res, address);\n return res.json() as Promise<{ unsignedTx: string }>;\n }\n}\n","/** Base class for all errors thrown by the @escro/sdk. */\nexport class EscroError extends Error {\n constructor(\n message: string,\n public readonly code: string = \"ESCRO_ERROR\",\n ) {\n super(message);\n this.name = \"EscroError\";\n }\n}\n\n/** The requested escrow was not found (HTTP 404). */\nexport class EscrowNotFoundError extends EscroError {\n constructor(address: string) {\n super(`Escrow not found: ${address}`, \"ESCROW_NOT_FOUND\");\n this.name = \"EscrowNotFoundError\";\n }\n}\n\n/** The operation is not valid for the escrow's current state (HTTP 409). */\nexport class EscrowStateError extends EscroError {\n constructor(message: string) {\n super(message, \"ESCROW_INVALID_STATE\");\n this.name = \"EscrowStateError\";\n }\n}\n\n/** Polling timed out after 24 hours without reaching the expected state. */\nexport class EscrowTimeoutError extends EscroError {\n constructor(address: string) {\n super(`Polling timed out after 24h for escrow: ${address}`, \"ESCROW_TIMEOUT\");\n this.name = \"EscrowTimeoutError\";\n }\n}\n\n/** The caller is not authorized to perform this action (HTTP 401/403). */\nexport class UnauthorizedError extends EscroError {\n constructor(message = \"Unauthorized\") {\n super(message, \"UNAUTHORIZED\");\n this.name = \"UnauthorizedError\";\n }\n}\n","import { EscrowTimeoutError } from \"./errors.js\";\n\nconst MS_5_MIN = 5 * 60 * 1_000;\nconst MS_30_MIN = 30 * 60 * 1_000;\nconst MS_24_H = 24 * 60 * 60 * 1_000;\n\n/**\n * Returns the next polling interval in ms based on total elapsed time.\n * 0 – 5 min → 15 s\n * 5 – 30 min → 30 s\n * 30 min – ∞ → 60 s\n */\nexport function backoffInterval(elapsedMs: number): number {\n if (elapsedMs < MS_5_MIN) return 15_000;\n if (elapsedMs < MS_30_MIN) return 30_000;\n return 60_000;\n}\n\n/** Resolves after `ms` milliseconds. */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Polls `fetcher` with exponential backoff until `predicate` returns true,\n * then returns the result. Throws {@link EscrowTimeoutError} after 24 hours.\n *\n * @param address - Escrow address used in the timeout error message.\n * @param fetcher - Async function that returns a value or null.\n * @param predicate - Returns true when polling should stop.\n * @param timeoutMs - Maximum total wait time in ms (default: 24 h).\n */\nexport async function pollUntil<T>(\n address: string,\n fetcher: () => Promise<T | null>,\n predicate: (result: T | null) => result is T,\n timeoutMs = MS_24_H,\n): Promise<T> {\n const deadline = Date.now() + timeoutMs;\n\n while (true) {\n const result = await fetcher();\n if (predicate(result)) return result;\n\n const elapsed = Date.now() - (deadline - timeoutMs);\n if (Date.now() >= deadline) {\n throw new EscrowTimeoutError(address);\n }\n\n const interval = backoffInterval(elapsed);\n // Clamp to remaining time so we don't sleep past the deadline\n const remaining = deadline - Date.now();\n await sleep(Math.min(interval, remaining));\n\n if (Date.now() >= deadline) {\n throw new EscrowTimeoutError(address);\n }\n }\n}\n","import { createHash } from \"node:crypto\";\nimport {\n Connection,\n Keypair,\n PublicKey,\n Transaction,\n TransactionInstruction,\n} from \"@solana/web3.js\";\nimport {\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n getAssociatedTokenAddressSync,\n createAssociatedTokenAccountInstruction,\n} from \"@solana/spl-token\";\n\n// ── Discriminator helper ───────────────────────────────────────────────────────\n\nfunction disc(name: string): Buffer {\n return Buffer.from(\n createHash(\"sha256\").update(`global:${name}`).digest(),\n ).subarray(0, 8);\n}\n\nconst DISC_RELEASE_PAYMENT = disc(\"release_payment\");\n\n// ── Constants ──────────────────────────────────────────────────────────────────\n\nconst PROGRAM_ID = new PublicKey(\"EjLpJ3obUYk1f2KDensU7UdGBZTxSdxufm7CSnMA3H5C\");\n\n/**\n * PlatformConfig account layout (after 8-byte Anchor discriminator):\n * fee_bps : u16 — offset 8..10\n * oracle_authority : Pubkey — offset 10..42\n * usdc_mint : Pubkey — offset 42..74\n * treasury : Pubkey — offset 74..106\n */\nexport async function fetchPlatformConfig(\n connection: Connection,\n): Promise<{ mint: PublicKey; treasury: PublicKey }> {\n const [pda] = PublicKey.findProgramAddressSync([Buffer.from(\"config\")], PROGRAM_ID);\n const info = await connection.getAccountInfo(pda);\n if (!info) throw new Error(\"PlatformConfig account not found on-chain\");\n return {\n mint: new PublicKey(info.data.slice(42, 74)),\n treasury: new PublicKey(info.data.slice(74, 106)),\n };\n}\n\n// ── Sign and submit ────────────────────────────────────────────────────────────\n\n/**\n * Decode a base64 unsigned transaction, sign it with `wallet`, submit to Solana,\n * and return the transaction signature.\n */\nexport async function signAndSend(\n base64Tx: string,\n wallet: Keypair,\n connection: Connection,\n): Promise<string> {\n const buf = Buffer.from(base64Tx, \"base64\");\n const tx = Transaction.from(buf);\n tx.partialSign(wallet);\n const raw = tx.serialize();\n const signature = await connection.sendRawTransaction(raw, {\n skipPreflight: false,\n });\n await connection.confirmTransaction(signature, \"confirmed\");\n return signature;\n}\n\n// ── release_payment transaction builder ───────────────────────────────────────\n\n/**\n * Build an unsigned `release_payment` transaction.\n * The buyer signs to approve payment to the assigned worker.\n *\n * Account order (matches the on-chain `ReleasePayment` context):\n * 0. buyer — Signer, writable\n * 1. platform_config — read\n * 2. mint — read\n * 3. escrow_account — writable\n * 4. vault — ATA(mint, escrowPda), writable\n * 5. worker_ata — ATA(mint, worker), writable\n * 6. treasury_ata — ATA(mint, treasury), writable\n * 7. worker — read\n * 8. treasury — read\n * 9. token_program — read\n * 10. associated_token_program — read\n */\nexport async function buildReleasePaymentTx(params: {\n buyer: PublicKey;\n escrowPda: PublicKey;\n worker: PublicKey;\n mint: PublicKey;\n treasury: PublicKey;\n connection: Connection;\n}): Promise<string> {\n const { buyer, escrowPda, worker, mint, treasury, connection } = params;\n\n const [platformConfig] = PublicKey.findProgramAddressSync(\n [Buffer.from(\"config\")],\n PROGRAM_ID,\n );\n const vault = getAssociatedTokenAddressSync(\n mint,\n escrowPda,\n true,\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n );\n const workerAta = getAssociatedTokenAddressSync(\n mint,\n worker,\n false,\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n );\n const treasuryAta = getAssociatedTokenAddressSync(\n mint,\n treasury,\n false,\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n );\n\n // Check which ATAs need to be created; the on-chain program has a hard\n // AccountNotInitialized guard (no init_if_needed), so we must ensure both\n // exist before the release_payment instruction runs.\n const [workerAtaInfo, treasuryAtaInfo] = await connection.getMultipleAccountsInfo([\n workerAta,\n treasuryAta,\n ]);\n\n const ix = new TransactionInstruction({\n programId: PROGRAM_ID,\n keys: [\n { pubkey: buyer, isSigner: true, isWritable: true },\n { pubkey: platformConfig, isSigner: false, isWritable: false },\n { pubkey: mint, isSigner: false, isWritable: false },\n { pubkey: escrowPda, isSigner: false, isWritable: true },\n { pubkey: vault, isSigner: false, isWritable: true },\n { pubkey: workerAta, isSigner: false, isWritable: true },\n { pubkey: treasuryAta, isSigner: false, isWritable: true },\n { pubkey: worker, isSigner: false, isWritable: false },\n { pubkey: treasury, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n ],\n data: DISC_RELEASE_PAYMENT,\n });\n\n const { blockhash } = await connection.getLatestBlockhash(\"confirmed\");\n const tx = new Transaction();\n tx.recentBlockhash = blockhash;\n tx.feePayer = buyer;\n\n if (!workerAtaInfo) {\n tx.add(\n createAssociatedTokenAccountInstruction(buyer, workerAta, worker, mint),\n );\n }\n if (!treasuryAtaInfo) {\n tx.add(\n createAssociatedTokenAccountInstruction(buyer, treasuryAta, treasury, mint),\n );\n }\n\n tx.add(ix);\n return tx.serialize({ requireAllSignatures: false }).toString(\"base64\");\n}\n"],"mappings":"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","names":["import_web3","nacl","bs58"]}
package/dist/index.d.cts CHANGED
@@ -15,7 +15,11 @@ interface EscroOptions {
15
15
  interface CreateEscrowParams {
16
16
  /** Full task specification uploaded to IPFS. */
17
17
  taskSpec: TaskSpec;
18
- /** Payment amount in μUSDC (1 USDC = 1_000_000). Minimum: 5_000_000. */
18
+ /**
19
+ * Worker's net payment in μUSDC (1 USDC = 1_000_000). Minimum: 5_000_000.
20
+ * The buyer is charged `amountUsdc + fee` at creation; the worker receives
21
+ * the full `amountUsdc` on settlement.
22
+ */
19
23
  amountUsdc: number;
20
24
  /** Unix timestamp (seconds) at which the escrow deadline expires. */
21
25
  deadlineSeconds: number;
package/dist/index.d.ts CHANGED
@@ -15,7 +15,11 @@ interface EscroOptions {
15
15
  interface CreateEscrowParams {
16
16
  /** Full task specification uploaded to IPFS. */
17
17
  taskSpec: TaskSpec;
18
- /** Payment amount in μUSDC (1 USDC = 1_000_000). Minimum: 5_000_000. */
18
+ /**
19
+ * Worker's net payment in μUSDC (1 USDC = 1_000_000). Minimum: 5_000_000.
20
+ * The buyer is charged `amountUsdc + fee` at creation; the worker receives
21
+ * the full `amountUsdc` on settlement.
22
+ */
19
23
  amountUsdc: number;
20
24
  /** Unix timestamp (seconds) at which the escrow deadline expires. */
21
25
  deadlineSeconds: number;
package/dist/index.js CHANGED
@@ -228,7 +228,8 @@ import {
228
228
  import {
229
229
  TOKEN_PROGRAM_ID,
230
230
  ASSOCIATED_TOKEN_PROGRAM_ID,
231
- getAssociatedTokenAddressSync
231
+ getAssociatedTokenAddressSync,
232
+ createAssociatedTokenAccountInstruction
232
233
  } from "@solana/spl-token";
233
234
  function disc(name) {
234
235
  return Buffer.from(
@@ -284,6 +285,10 @@ async function buildReleasePaymentTx(params) {
284
285
  TOKEN_PROGRAM_ID,
285
286
  ASSOCIATED_TOKEN_PROGRAM_ID
286
287
  );
288
+ const [workerAtaInfo, treasuryAtaInfo] = await connection.getMultipleAccountsInfo([
289
+ workerAta,
290
+ treasuryAta
291
+ ]);
287
292
  const ix = new TransactionInstruction({
288
293
  programId: PROGRAM_ID,
289
294
  keys: [
@@ -305,6 +310,16 @@ async function buildReleasePaymentTx(params) {
305
310
  const tx = new Transaction();
306
311
  tx.recentBlockhash = blockhash;
307
312
  tx.feePayer = buyer;
313
+ if (!workerAtaInfo) {
314
+ tx.add(
315
+ createAssociatedTokenAccountInstruction(buyer, workerAta, worker, mint)
316
+ );
317
+ }
318
+ if (!treasuryAtaInfo) {
319
+ tx.add(
320
+ createAssociatedTokenAccountInstruction(buyer, treasuryAta, treasury, mint)
321
+ );
322
+ }
308
323
  tx.add(ix);
309
324
  return tx.serialize({ requireAllSignatures: false }).toString("base64");
310
325
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/api.ts","../src/errors.ts","../src/poll.ts","../src/solana.ts"],"sourcesContent":["import { Connection, PublicKey } from \"@solana/web3.js\";\nimport type { EscrowAccount, EscrowState } from \"@escro/shared\";\nimport type {\n CreateEscrowParams,\n CreateEscrowResult,\n EscroOptions,\n ListOptions,\n PaginatedResult,\n PollOptions,\n RaiseDisputeParams,\n SubmitDeliverableParams,\n} from \"./types.js\";\nimport { ApiClient } from \"./api.js\";\nimport { EscrowNotFoundError } from \"./errors.js\";\nimport { pollUntil } from \"./poll.js\";\nimport { buildReleasePaymentTx, fetchPlatformConfig, signAndSend } from \"./solana.js\";\n\nexport class Escro {\n private readonly connection: Connection;\n private readonly api: ApiClient;\n private readonly options: EscroOptions;\n\n constructor(options: EscroOptions) {\n this.options = options;\n this.connection = new Connection(options.rpcUrl, \"confirmed\");\n this.api = new ApiClient(options.apiUrl, options.wallet);\n }\n\n // ── Buyer Bot ────────────────────────────────────────────────────────────────\n\n /**\n * Create a new escrow: registers with the API, signs and submits the\n * on-chain `create_escrow` transaction.\n *\n * @returns `{ escrowId, escrowPda, signature }` — use `escrowPda` for all subsequent calls.\n */\n async createEscrow(params: CreateEscrowParams): Promise<CreateEscrowResult> {\n const { escrowId, escrowPda, unsignedTx } = await this.api.createEscrow(params);\n const signature = await signAndSend(unsignedTx, this.options.wallet, this.connection);\n return { escrowId, escrowPda, signature };\n }\n\n /**\n * Release payment to the worker. Buyer must be the wallet in the constructor.\n * Updates API DB state, then builds and submits the `release_payment` on-chain tx.\n *\n * @returns Solana transaction signature.\n */\n async releasePayment(address: string): Promise<string> {\n // Fetch escrow metadata for worker pubkey + mint\n const escrow = await this.api.getEscrow(address);\n if (!escrow.taker) {\n throw new EscrowNotFoundError(`Escrow ${address} has no assigned worker`);\n }\n\n // Fetch platform config for treasury pubkey + usdc mint\n const { treasury, mint } = await fetchPlatformConfig(this.connection);\n\n // Update DB state (optimistic — on-chain reconciliation runs asynchronously)\n await this.api.releasePaymentDb(address);\n\n // Build, sign, and submit the on-chain instruction\n const unsignedTx = await buildReleasePaymentTx({\n buyer: this.options.wallet.publicKey,\n escrowPda: new PublicKey(address),\n worker: new PublicKey(escrow.taker),\n mint,\n treasury,\n connection: this.connection,\n });\n\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n /**\n * Raise a dispute for an escrow. Either the buyer or the assigned worker\n * may call this. Signs and submits the `raise_dispute` on-chain tx.\n *\n * @returns Solana transaction signature.\n */\n async raiseDispute(address: string, params: RaiseDisputeParams): Promise<string> {\n const { unsignedTx } = await this.api.raiseDispute(address, params);\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n /**\n * Cancel a funded escrow before any worker has claimed it.\n * Buyer must be the wallet in the constructor. Only valid when state is `FUNDED`.\n * Signs and submits the `cancel_escrow` on-chain tx; full USDC refund to buyer.\n *\n * @returns Solana transaction signature.\n */\n async cancelEscrow(address: string): Promise<string> {\n const { unsignedTx } = await this.api.cancelEscrow(address);\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n // ── Worker Bot ───────────────────────────────────────────────────────────────\n\n /**\n * Claim an assigned task. Worker must be the wallet in the constructor.\n * Signs and submits the `claim_task` on-chain tx.\n *\n * @returns Solana transaction signature.\n */\n async claimTask(address: string): Promise<string> {\n const { unsignedTx } = await this.api.claimTask(address);\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n /**\n * Submit a deliverable for oracle evaluation. Worker must be the wallet.\n * Signs and submits the `submit_deliverable` on-chain tx.\n *\n * @returns Solana transaction signature.\n */\n async submitDeliverable(address: string, params: SubmitDeliverableParams): Promise<string> {\n const { unsignedTx } = await this.api.submitDeliverable(address, params);\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n /**\n * List tasks assigned to the wallet's public key.\n * Optionally filter by state(s) and paginate results.\n *\n * If `options.poll` is true, polls with exponential backoff until at least\n * one task is returned.\n *\n * @param state - Filter by one or more states (first state used as API filter).\n * @param options - Polling, pagination (limit/offset).\n */\n async getMyTasks(\n state?: EscrowState[],\n options?: PollOptions & ListOptions,\n ): Promise<PaginatedResult<EscrowAccount>> {\n const assignedTo = this.options.wallet.publicKey.toBase58();\n const params: Parameters<ApiClient[\"listEscrows\"]>[0] = {\n assignedTo,\n ...(state?.[0] != null && { state: state[0] }),\n ...(options?.limit != null && { limit: options.limit }),\n ...(options?.offset != null && { offset: options.offset }),\n };\n\n if (!options?.poll) {\n return this.api.listEscrows(params);\n }\n\n const fetcher = () =>\n this.api\n .listEscrows(params)\n .then((result) => (result.items.length > 0 ? result : null));\n\n return pollUntil(\n assignedTo,\n fetcher,\n (r): r is PaginatedResult<EscrowAccount> => r !== null,\n options.timeoutMs,\n );\n }\n\n // ── Shared ───────────────────────────────────────────────────────────────────\n\n /**\n * Fetch an escrow by its PDA address.\n * If `options.poll` is true, polls with exponential backoff until the escrow\n * appears (useful immediately after a create tx before the API DB syncs).\n */\n async getEscrow(address: string, options?: PollOptions): Promise<EscrowAccount> {\n if (!options?.poll) {\n return this.api.getEscrow(address);\n }\n\n return pollUntil(\n address,\n () =>\n this.api\n .getEscrow(address)\n .catch((e: unknown) => (e instanceof EscrowNotFoundError ? null : Promise.reject(e))),\n (r): r is EscrowAccount => r !== null,\n options.timeoutMs,\n );\n }\n}\n","import nacl from \"tweetnacl\";\nimport bs58 from \"bs58\";\nimport type { Keypair } from \"@solana/web3.js\";\nimport type { EscrowAccount, EscrowState } from \"@escro/shared\";\nimport type {\n CreateEscrowParams,\n ListOptions,\n PaginatedResult,\n RaiseDisputeParams,\n SerializedEscrow,\n SubmitDeliverableParams,\n} from \"./types.js\";\nimport {\n EscroError,\n EscrowNotFoundError,\n EscrowStateError,\n UnauthorizedError,\n} from \"./errors.js\";\n\n// ── Auth header builder ────────────────────────────────────────────────────────\n\nfunction authHeaders(\n wallet: Keypair,\n method: string,\n path: string,\n): Record<string, string> {\n const timestamp = Date.now();\n const message = `escro:${timestamp}:${method}:${path}`;\n const msgBytes = new TextEncoder().encode(message);\n const sigBytes = nacl.sign.detached(msgBytes, wallet.secretKey);\n return {\n \"x-wallet-address\": wallet.publicKey.toBase58(),\n \"x-signature\": bs58.encode(sigBytes),\n \"x-timestamp\": String(timestamp),\n };\n}\n\n// ── Deserialization ────────────────────────────────────────────────────────────\n\nfunction deserialize(raw: SerializedEscrow): EscrowAccount {\n return { ...raw, amount: BigInt(raw.amount) };\n}\n\n// ── Error handling ─────────────────────────────────────────────────────────────\n\nasync function handleError(res: Response, address?: string): Promise<never> {\n const body = (await res.json().catch(() => ({}))) as {\n error?: string;\n code?: string;\n };\n const msg = body.error ?? `HTTP ${res.status}`;\n if (res.status === 404) throw new EscrowNotFoundError(address ?? msg);\n if (res.status === 409) throw new EscrowStateError(msg);\n if (res.status === 401 || res.status === 403) throw new UnauthorizedError(msg);\n throw new EscroError(msg, body.code ?? \"UNKNOWN\");\n}\n\n// ── API client ─────────────────────────────────────────────────────────────────\n\nexport class ApiClient {\n constructor(\n private readonly baseUrl: string,\n private readonly wallet: Keypair,\n ) {}\n\n private url(path: string): string {\n return `${this.baseUrl}${path}`;\n }\n\n /** GET /v1/escrows/:address */\n async getEscrow(address: string): Promise<EscrowAccount> {\n const path = `/v1/escrows/${address}`;\n const res = await fetch(this.url(path));\n if (!res.ok) await handleError(res, address);\n return deserialize((await res.json()) as SerializedEscrow);\n }\n\n /** GET /v1/escrows?assignedTo=...&state=... */\n async listEscrows(params: {\n assignedTo?: string;\n state?: EscrowState;\n limit?: number;\n offset?: number;\n }): Promise<PaginatedResult<EscrowAccount>> {\n const qs = new URLSearchParams();\n if (params.assignedTo) qs.set(\"assignedTo\", params.assignedTo);\n if (params.state) qs.set(\"state\", params.state);\n if (params.limit != null) qs.set(\"limit\", String(params.limit));\n if (params.offset != null) qs.set(\"offset\", String(params.offset));\n\n const path = `/v1/escrows?${qs.toString()}`;\n const res = await fetch(this.url(path));\n if (!res.ok) await handleError(res);\n const body = (await res.json()) as {\n items: SerializedEscrow[];\n total: number;\n limit: number;\n offset: number;\n };\n return {\n items: body.items.map(deserialize),\n total: body.total,\n limit: body.limit,\n offset: body.offset,\n };\n }\n\n /**\n * POST /v1/escrows — create escrow, returns unsigned tx + ids.\n * Requires auth.\n */\n async createEscrow(params: CreateEscrowParams): Promise<{\n escrowId: string;\n escrowPda: string;\n unsignedTx: string;\n }> {\n const path = \"/v1/escrows\";\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: { ...authHeaders(this.wallet, \"POST\", path), \"content-type\": \"application/json\" },\n body: JSON.stringify({\n taskSpec: params.taskSpec,\n amountUsdc: params.amountUsdc,\n deadlineSeconds: params.deadlineSeconds,\n assignedWorker: params.assignedWorker,\n }),\n });\n if (!res.ok) await handleError(res);\n return res.json() as Promise<{ escrowId: string; escrowPda: string; unsignedTx: string }>;\n }\n\n /**\n * POST /v1/escrows/:address/claim — returns unsigned tx.\n * Requires auth (worker).\n */\n async claimTask(address: string): Promise<{ unsignedTx: string }> {\n const path = `/v1/escrows/${address}/claim`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: authHeaders(this.wallet, \"POST\", path),\n });\n if (!res.ok) await handleError(res, address);\n return res.json() as Promise<{ unsignedTx: string }>;\n }\n\n /**\n * POST /v1/escrows/:address/submit — returns unsigned tx.\n * Requires auth (worker).\n */\n async submitDeliverable(\n address: string,\n params: SubmitDeliverableParams,\n ): Promise<{ unsignedTx: string }> {\n const path = `/v1/escrows/${address}/submit`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: { ...authHeaders(this.wallet, \"POST\", path), \"content-type\": \"application/json\" },\n body: JSON.stringify({\n contentHash: params.contentHash,\n proofUri: params.proofUri,\n }),\n });\n if (!res.ok) await handleError(res, address);\n return res.json() as Promise<{ unsignedTx: string }>;\n }\n\n /**\n * POST /v1/escrows/:address/release — DB-only state update.\n * Requires auth (buyer). No on-chain tx returned.\n */\n async releasePaymentDb(address: string): Promise<void> {\n const path = `/v1/escrows/${address}/release`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: authHeaders(this.wallet, \"POST\", path),\n });\n if (!res.ok) await handleError(res, address);\n }\n\n /**\n * POST /v1/escrows/:address/cancel — returns unsigned tx.\n * Requires auth (buyer). Only valid when state is FUNDED.\n */\n async cancelEscrow(address: string): Promise<{ unsignedTx: string }> {\n const path = `/v1/escrows/${address}/cancel`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: authHeaders(this.wallet, \"POST\", path),\n });\n if (!res.ok) await handleError(res, address);\n return res.json() as Promise<{ unsignedTx: string }>;\n }\n\n /**\n * POST /v1/escrows/:address/dispute — returns unsigned tx.\n * Requires auth (buyer or worker).\n */\n async raiseDispute(\n address: string,\n params: RaiseDisputeParams,\n ): Promise<{ unsignedTx: string }> {\n const path = `/v1/escrows/${address}/dispute`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: { ...authHeaders(this.wallet, \"POST\", path), \"content-type\": \"application/json\" },\n body: JSON.stringify({ reason: params.reason, evidence: params.evidence }),\n });\n if (!res.ok) await handleError(res, address);\n return res.json() as Promise<{ unsignedTx: string }>;\n }\n}\n","/** Base class for all errors thrown by the @escro/sdk. */\nexport class EscroError extends Error {\n constructor(\n message: string,\n public readonly code: string = \"ESCRO_ERROR\",\n ) {\n super(message);\n this.name = \"EscroError\";\n }\n}\n\n/** The requested escrow was not found (HTTP 404). */\nexport class EscrowNotFoundError extends EscroError {\n constructor(address: string) {\n super(`Escrow not found: ${address}`, \"ESCROW_NOT_FOUND\");\n this.name = \"EscrowNotFoundError\";\n }\n}\n\n/** The operation is not valid for the escrow's current state (HTTP 409). */\nexport class EscrowStateError extends EscroError {\n constructor(message: string) {\n super(message, \"ESCROW_INVALID_STATE\");\n this.name = \"EscrowStateError\";\n }\n}\n\n/** Polling timed out after 24 hours without reaching the expected state. */\nexport class EscrowTimeoutError extends EscroError {\n constructor(address: string) {\n super(`Polling timed out after 24h for escrow: ${address}`, \"ESCROW_TIMEOUT\");\n this.name = \"EscrowTimeoutError\";\n }\n}\n\n/** The caller is not authorized to perform this action (HTTP 401/403). */\nexport class UnauthorizedError extends EscroError {\n constructor(message = \"Unauthorized\") {\n super(message, \"UNAUTHORIZED\");\n this.name = \"UnauthorizedError\";\n }\n}\n","import { EscrowTimeoutError } from \"./errors.js\";\n\nconst MS_5_MIN = 5 * 60 * 1_000;\nconst MS_30_MIN = 30 * 60 * 1_000;\nconst MS_24_H = 24 * 60 * 60 * 1_000;\n\n/**\n * Returns the next polling interval in ms based on total elapsed time.\n * 0 – 5 min → 15 s\n * 5 – 30 min → 30 s\n * 30 min – ∞ → 60 s\n */\nexport function backoffInterval(elapsedMs: number): number {\n if (elapsedMs < MS_5_MIN) return 15_000;\n if (elapsedMs < MS_30_MIN) return 30_000;\n return 60_000;\n}\n\n/** Resolves after `ms` milliseconds. */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Polls `fetcher` with exponential backoff until `predicate` returns true,\n * then returns the result. Throws {@link EscrowTimeoutError} after 24 hours.\n *\n * @param address - Escrow address used in the timeout error message.\n * @param fetcher - Async function that returns a value or null.\n * @param predicate - Returns true when polling should stop.\n * @param timeoutMs - Maximum total wait time in ms (default: 24 h).\n */\nexport async function pollUntil<T>(\n address: string,\n fetcher: () => Promise<T | null>,\n predicate: (result: T | null) => result is T,\n timeoutMs = MS_24_H,\n): Promise<T> {\n const deadline = Date.now() + timeoutMs;\n\n while (true) {\n const result = await fetcher();\n if (predicate(result)) return result;\n\n const elapsed = Date.now() - (deadline - timeoutMs);\n if (Date.now() >= deadline) {\n throw new EscrowTimeoutError(address);\n }\n\n const interval = backoffInterval(elapsed);\n // Clamp to remaining time so we don't sleep past the deadline\n const remaining = deadline - Date.now();\n await sleep(Math.min(interval, remaining));\n\n if (Date.now() >= deadline) {\n throw new EscrowTimeoutError(address);\n }\n }\n}\n","import { createHash } from \"node:crypto\";\nimport {\n Connection,\n Keypair,\n PublicKey,\n Transaction,\n TransactionInstruction,\n} from \"@solana/web3.js\";\nimport {\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n getAssociatedTokenAddressSync,\n} from \"@solana/spl-token\";\n\n// ── Discriminator helper ───────────────────────────────────────────────────────\n\nfunction disc(name: string): Buffer {\n return Buffer.from(\n createHash(\"sha256\").update(`global:${name}`).digest(),\n ).subarray(0, 8);\n}\n\nconst DISC_RELEASE_PAYMENT = disc(\"release_payment\");\n\n// ── Constants ──────────────────────────────────────────────────────────────────\n\nconst PROGRAM_ID = new PublicKey(\"EjLpJ3obUYk1f2KDensU7UdGBZTxSdxufm7CSnMA3H5C\");\n\n/**\n * PlatformConfig account layout (after 8-byte Anchor discriminator):\n * fee_bps : u16 — offset 8..10\n * oracle_authority : Pubkey — offset 10..42\n * usdc_mint : Pubkey — offset 42..74\n * treasury : Pubkey — offset 74..106\n */\nexport async function fetchPlatformConfig(\n connection: Connection,\n): Promise<{ mint: PublicKey; treasury: PublicKey }> {\n const [pda] = PublicKey.findProgramAddressSync([Buffer.from(\"config\")], PROGRAM_ID);\n const info = await connection.getAccountInfo(pda);\n if (!info) throw new Error(\"PlatformConfig account not found on-chain\");\n return {\n mint: new PublicKey(info.data.slice(42, 74)),\n treasury: new PublicKey(info.data.slice(74, 106)),\n };\n}\n\n// ── Sign and submit ────────────────────────────────────────────────────────────\n\n/**\n * Decode a base64 unsigned transaction, sign it with `wallet`, submit to Solana,\n * and return the transaction signature.\n */\nexport async function signAndSend(\n base64Tx: string,\n wallet: Keypair,\n connection: Connection,\n): Promise<string> {\n const buf = Buffer.from(base64Tx, \"base64\");\n const tx = Transaction.from(buf);\n tx.partialSign(wallet);\n const raw = tx.serialize();\n const signature = await connection.sendRawTransaction(raw, {\n skipPreflight: false,\n });\n await connection.confirmTransaction(signature, \"confirmed\");\n return signature;\n}\n\n// ── release_payment transaction builder ───────────────────────────────────────\n\n/**\n * Build an unsigned `release_payment` transaction.\n * The buyer signs to approve payment to the assigned worker.\n *\n * Account order (matches the on-chain `ReleasePayment` context):\n * 0. buyer — Signer, writable\n * 1. platform_config — read\n * 2. mint — read\n * 3. escrow_account — writable\n * 4. vault — ATA(mint, escrowPda), writable\n * 5. worker_ata — ATA(mint, worker), writable\n * 6. treasury_ata — ATA(mint, treasury), writable\n * 7. worker — read\n * 8. treasury — read\n * 9. token_program — read\n * 10. associated_token_program — read\n */\nexport async function buildReleasePaymentTx(params: {\n buyer: PublicKey;\n escrowPda: PublicKey;\n worker: PublicKey;\n mint: PublicKey;\n treasury: PublicKey;\n connection: Connection;\n}): Promise<string> {\n const { buyer, escrowPda, worker, mint, treasury, connection } = params;\n\n const [platformConfig] = PublicKey.findProgramAddressSync(\n [Buffer.from(\"config\")],\n PROGRAM_ID,\n );\n const vault = getAssociatedTokenAddressSync(\n mint,\n escrowPda,\n true,\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n );\n const workerAta = getAssociatedTokenAddressSync(\n mint,\n worker,\n false,\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n );\n const treasuryAta = getAssociatedTokenAddressSync(\n mint,\n treasury,\n false,\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n );\n\n const ix = new TransactionInstruction({\n programId: PROGRAM_ID,\n keys: [\n { pubkey: buyer, isSigner: true, isWritable: true },\n { pubkey: platformConfig, isSigner: false, isWritable: false },\n { pubkey: mint, isSigner: false, isWritable: false },\n { pubkey: escrowPda, isSigner: false, isWritable: true },\n { pubkey: vault, isSigner: false, isWritable: true },\n { pubkey: workerAta, isSigner: false, isWritable: true },\n { pubkey: treasuryAta, isSigner: false, isWritable: true },\n { pubkey: worker, isSigner: false, isWritable: false },\n { pubkey: treasury, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n ],\n data: DISC_RELEASE_PAYMENT,\n });\n\n const { blockhash } = await connection.getLatestBlockhash(\"confirmed\");\n const tx = new Transaction();\n tx.recentBlockhash = blockhash;\n tx.feePayer = buyer;\n tx.add(ix);\n return tx.serialize({ requireAllSignatures: false }).toString(\"base64\");\n}\n"],"mappings":"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","names":["Connection","PublicKey","Connection","PublicKey"]}
1
+ {"version":3,"sources":["../src/client.ts","../src/api.ts","../src/errors.ts","../src/poll.ts","../src/solana.ts"],"sourcesContent":["import { Connection, PublicKey } from \"@solana/web3.js\";\nimport type { EscrowAccount, EscrowState } from \"@escro/shared\";\nimport type {\n CreateEscrowParams,\n CreateEscrowResult,\n EscroOptions,\n ListOptions,\n PaginatedResult,\n PollOptions,\n RaiseDisputeParams,\n SubmitDeliverableParams,\n} from \"./types.js\";\nimport { ApiClient } from \"./api.js\";\nimport { EscrowNotFoundError } from \"./errors.js\";\nimport { pollUntil } from \"./poll.js\";\nimport { buildReleasePaymentTx, fetchPlatformConfig, signAndSend } from \"./solana.js\";\n\nexport class Escro {\n private readonly connection: Connection;\n private readonly api: ApiClient;\n private readonly options: EscroOptions;\n\n constructor(options: EscroOptions) {\n this.options = options;\n this.connection = new Connection(options.rpcUrl, \"confirmed\");\n this.api = new ApiClient(options.apiUrl, options.wallet);\n }\n\n // ── Buyer Bot ────────────────────────────────────────────────────────────────\n\n /**\n * Create a new escrow: registers with the API, signs and submits the\n * on-chain `create_escrow` transaction.\n *\n * @returns `{ escrowId, escrowPda, signature }` — use `escrowPda` for all subsequent calls.\n */\n async createEscrow(params: CreateEscrowParams): Promise<CreateEscrowResult> {\n const { escrowId, escrowPda, unsignedTx } = await this.api.createEscrow(params);\n const signature = await signAndSend(unsignedTx, this.options.wallet, this.connection);\n return { escrowId, escrowPda, signature };\n }\n\n /**\n * Release payment to the worker. Buyer must be the wallet in the constructor.\n * Updates API DB state, then builds and submits the `release_payment` on-chain tx.\n *\n * @returns Solana transaction signature.\n */\n async releasePayment(address: string): Promise<string> {\n // Fetch escrow metadata for worker pubkey + mint\n const escrow = await this.api.getEscrow(address);\n if (!escrow.taker) {\n throw new EscrowNotFoundError(`Escrow ${address} has no assigned worker`);\n }\n\n // Fetch platform config for treasury pubkey + usdc mint\n const { treasury, mint } = await fetchPlatformConfig(this.connection);\n\n // Update DB state (optimistic — on-chain reconciliation runs asynchronously)\n await this.api.releasePaymentDb(address);\n\n // Build, sign, and submit the on-chain instruction\n const unsignedTx = await buildReleasePaymentTx({\n buyer: this.options.wallet.publicKey,\n escrowPda: new PublicKey(address),\n worker: new PublicKey(escrow.taker),\n mint,\n treasury,\n connection: this.connection,\n });\n\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n /**\n * Raise a dispute for an escrow. Either the buyer or the assigned worker\n * may call this. Signs and submits the `raise_dispute` on-chain tx.\n *\n * @returns Solana transaction signature.\n */\n async raiseDispute(address: string, params: RaiseDisputeParams): Promise<string> {\n const { unsignedTx } = await this.api.raiseDispute(address, params);\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n /**\n * Cancel a funded escrow before any worker has claimed it.\n * Buyer must be the wallet in the constructor. Only valid when state is `FUNDED`.\n * Signs and submits the `cancel_escrow` on-chain tx; full USDC refund to buyer.\n *\n * @returns Solana transaction signature.\n */\n async cancelEscrow(address: string): Promise<string> {\n const { unsignedTx } = await this.api.cancelEscrow(address);\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n // ── Worker Bot ───────────────────────────────────────────────────────────────\n\n /**\n * Claim an assigned task. Worker must be the wallet in the constructor.\n * Signs and submits the `claim_task` on-chain tx.\n *\n * @returns Solana transaction signature.\n */\n async claimTask(address: string): Promise<string> {\n const { unsignedTx } = await this.api.claimTask(address);\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n /**\n * Submit a deliverable for oracle evaluation. Worker must be the wallet.\n * Signs and submits the `submit_deliverable` on-chain tx.\n *\n * @returns Solana transaction signature.\n */\n async submitDeliverable(address: string, params: SubmitDeliverableParams): Promise<string> {\n const { unsignedTx } = await this.api.submitDeliverable(address, params);\n return signAndSend(unsignedTx, this.options.wallet, this.connection);\n }\n\n /**\n * List tasks assigned to the wallet's public key.\n * Optionally filter by state(s) and paginate results.\n *\n * If `options.poll` is true, polls with exponential backoff until at least\n * one task is returned.\n *\n * @param state - Filter by one or more states (first state used as API filter).\n * @param options - Polling, pagination (limit/offset).\n */\n async getMyTasks(\n state?: EscrowState[],\n options?: PollOptions & ListOptions,\n ): Promise<PaginatedResult<EscrowAccount>> {\n const assignedTo = this.options.wallet.publicKey.toBase58();\n const params: Parameters<ApiClient[\"listEscrows\"]>[0] = {\n assignedTo,\n ...(state?.[0] != null && { state: state[0] }),\n ...(options?.limit != null && { limit: options.limit }),\n ...(options?.offset != null && { offset: options.offset }),\n };\n\n if (!options?.poll) {\n return this.api.listEscrows(params);\n }\n\n const fetcher = () =>\n this.api\n .listEscrows(params)\n .then((result) => (result.items.length > 0 ? result : null));\n\n return pollUntil(\n assignedTo,\n fetcher,\n (r): r is PaginatedResult<EscrowAccount> => r !== null,\n options.timeoutMs,\n );\n }\n\n // ── Shared ───────────────────────────────────────────────────────────────────\n\n /**\n * Fetch an escrow by its PDA address.\n * If `options.poll` is true, polls with exponential backoff until the escrow\n * appears (useful immediately after a create tx before the API DB syncs).\n */\n async getEscrow(address: string, options?: PollOptions): Promise<EscrowAccount> {\n if (!options?.poll) {\n return this.api.getEscrow(address);\n }\n\n return pollUntil(\n address,\n () =>\n this.api\n .getEscrow(address)\n .catch((e: unknown) => (e instanceof EscrowNotFoundError ? null : Promise.reject(e))),\n (r): r is EscrowAccount => r !== null,\n options.timeoutMs,\n );\n }\n}\n","import nacl from \"tweetnacl\";\nimport bs58 from \"bs58\";\nimport type { Keypair } from \"@solana/web3.js\";\nimport type { EscrowAccount, EscrowState } from \"@escro/shared\";\nimport type {\n CreateEscrowParams,\n ListOptions,\n PaginatedResult,\n RaiseDisputeParams,\n SerializedEscrow,\n SubmitDeliverableParams,\n} from \"./types.js\";\nimport {\n EscroError,\n EscrowNotFoundError,\n EscrowStateError,\n UnauthorizedError,\n} from \"./errors.js\";\n\n// ── Auth header builder ────────────────────────────────────────────────────────\n\nfunction authHeaders(\n wallet: Keypair,\n method: string,\n path: string,\n): Record<string, string> {\n const timestamp = Date.now();\n const message = `escro:${timestamp}:${method}:${path}`;\n const msgBytes = new TextEncoder().encode(message);\n const sigBytes = nacl.sign.detached(msgBytes, wallet.secretKey);\n return {\n \"x-wallet-address\": wallet.publicKey.toBase58(),\n \"x-signature\": bs58.encode(sigBytes),\n \"x-timestamp\": String(timestamp),\n };\n}\n\n// ── Deserialization ────────────────────────────────────────────────────────────\n\nfunction deserialize(raw: SerializedEscrow): EscrowAccount {\n return { ...raw, amount: BigInt(raw.amount) };\n}\n\n// ── Error handling ─────────────────────────────────────────────────────────────\n\nasync function handleError(res: Response, address?: string): Promise<never> {\n const body = (await res.json().catch(() => ({}))) as {\n error?: string;\n code?: string;\n };\n const msg = body.error ?? `HTTP ${res.status}`;\n if (res.status === 404) throw new EscrowNotFoundError(address ?? msg);\n if (res.status === 409) throw new EscrowStateError(msg);\n if (res.status === 401 || res.status === 403) throw new UnauthorizedError(msg);\n throw new EscroError(msg, body.code ?? \"UNKNOWN\");\n}\n\n// ── API client ─────────────────────────────────────────────────────────────────\n\nexport class ApiClient {\n constructor(\n private readonly baseUrl: string,\n private readonly wallet: Keypair,\n ) {}\n\n private url(path: string): string {\n return `${this.baseUrl}${path}`;\n }\n\n /** GET /v1/escrows/:address */\n async getEscrow(address: string): Promise<EscrowAccount> {\n const path = `/v1/escrows/${address}`;\n const res = await fetch(this.url(path));\n if (!res.ok) await handleError(res, address);\n return deserialize((await res.json()) as SerializedEscrow);\n }\n\n /** GET /v1/escrows?assignedTo=...&state=... */\n async listEscrows(params: {\n assignedTo?: string;\n state?: EscrowState;\n limit?: number;\n offset?: number;\n }): Promise<PaginatedResult<EscrowAccount>> {\n const qs = new URLSearchParams();\n if (params.assignedTo) qs.set(\"assignedTo\", params.assignedTo);\n if (params.state) qs.set(\"state\", params.state);\n if (params.limit != null) qs.set(\"limit\", String(params.limit));\n if (params.offset != null) qs.set(\"offset\", String(params.offset));\n\n const path = `/v1/escrows?${qs.toString()}`;\n const res = await fetch(this.url(path));\n if (!res.ok) await handleError(res);\n const body = (await res.json()) as {\n items: SerializedEscrow[];\n total: number;\n limit: number;\n offset: number;\n };\n return {\n items: body.items.map(deserialize),\n total: body.total,\n limit: body.limit,\n offset: body.offset,\n };\n }\n\n /**\n * POST /v1/escrows — create escrow, returns unsigned tx + ids.\n * Requires auth.\n */\n async createEscrow(params: CreateEscrowParams): Promise<{\n escrowId: string;\n escrowPda: string;\n unsignedTx: string;\n }> {\n const path = \"/v1/escrows\";\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: { ...authHeaders(this.wallet, \"POST\", path), \"content-type\": \"application/json\" },\n body: JSON.stringify({\n taskSpec: params.taskSpec,\n amountUsdc: params.amountUsdc,\n deadlineSeconds: params.deadlineSeconds,\n assignedWorker: params.assignedWorker,\n }),\n });\n if (!res.ok) await handleError(res);\n return res.json() as Promise<{ escrowId: string; escrowPda: string; unsignedTx: string }>;\n }\n\n /**\n * POST /v1/escrows/:address/claim — returns unsigned tx.\n * Requires auth (worker).\n */\n async claimTask(address: string): Promise<{ unsignedTx: string }> {\n const path = `/v1/escrows/${address}/claim`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: authHeaders(this.wallet, \"POST\", path),\n });\n if (!res.ok) await handleError(res, address);\n return res.json() as Promise<{ unsignedTx: string }>;\n }\n\n /**\n * POST /v1/escrows/:address/submit — returns unsigned tx.\n * Requires auth (worker).\n */\n async submitDeliverable(\n address: string,\n params: SubmitDeliverableParams,\n ): Promise<{ unsignedTx: string }> {\n const path = `/v1/escrows/${address}/submit`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: { ...authHeaders(this.wallet, \"POST\", path), \"content-type\": \"application/json\" },\n body: JSON.stringify({\n contentHash: params.contentHash,\n proofUri: params.proofUri,\n }),\n });\n if (!res.ok) await handleError(res, address);\n return res.json() as Promise<{ unsignedTx: string }>;\n }\n\n /**\n * POST /v1/escrows/:address/release — DB-only state update.\n * Requires auth (buyer). No on-chain tx returned.\n */\n async releasePaymentDb(address: string): Promise<void> {\n const path = `/v1/escrows/${address}/release`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: authHeaders(this.wallet, \"POST\", path),\n });\n if (!res.ok) await handleError(res, address);\n }\n\n /**\n * POST /v1/escrows/:address/cancel — returns unsigned tx.\n * Requires auth (buyer). Only valid when state is FUNDED.\n */\n async cancelEscrow(address: string): Promise<{ unsignedTx: string }> {\n const path = `/v1/escrows/${address}/cancel`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: authHeaders(this.wallet, \"POST\", path),\n });\n if (!res.ok) await handleError(res, address);\n return res.json() as Promise<{ unsignedTx: string }>;\n }\n\n /**\n * POST /v1/escrows/:address/dispute — returns unsigned tx.\n * Requires auth (buyer or worker).\n */\n async raiseDispute(\n address: string,\n params: RaiseDisputeParams,\n ): Promise<{ unsignedTx: string }> {\n const path = `/v1/escrows/${address}/dispute`;\n const res = await fetch(this.url(path), {\n method: \"POST\",\n headers: { ...authHeaders(this.wallet, \"POST\", path), \"content-type\": \"application/json\" },\n body: JSON.stringify({ reason: params.reason, evidence: params.evidence }),\n });\n if (!res.ok) await handleError(res, address);\n return res.json() as Promise<{ unsignedTx: string }>;\n }\n}\n","/** Base class for all errors thrown by the @escro/sdk. */\nexport class EscroError extends Error {\n constructor(\n message: string,\n public readonly code: string = \"ESCRO_ERROR\",\n ) {\n super(message);\n this.name = \"EscroError\";\n }\n}\n\n/** The requested escrow was not found (HTTP 404). */\nexport class EscrowNotFoundError extends EscroError {\n constructor(address: string) {\n super(`Escrow not found: ${address}`, \"ESCROW_NOT_FOUND\");\n this.name = \"EscrowNotFoundError\";\n }\n}\n\n/** The operation is not valid for the escrow's current state (HTTP 409). */\nexport class EscrowStateError extends EscroError {\n constructor(message: string) {\n super(message, \"ESCROW_INVALID_STATE\");\n this.name = \"EscrowStateError\";\n }\n}\n\n/** Polling timed out after 24 hours without reaching the expected state. */\nexport class EscrowTimeoutError extends EscroError {\n constructor(address: string) {\n super(`Polling timed out after 24h for escrow: ${address}`, \"ESCROW_TIMEOUT\");\n this.name = \"EscrowTimeoutError\";\n }\n}\n\n/** The caller is not authorized to perform this action (HTTP 401/403). */\nexport class UnauthorizedError extends EscroError {\n constructor(message = \"Unauthorized\") {\n super(message, \"UNAUTHORIZED\");\n this.name = \"UnauthorizedError\";\n }\n}\n","import { EscrowTimeoutError } from \"./errors.js\";\n\nconst MS_5_MIN = 5 * 60 * 1_000;\nconst MS_30_MIN = 30 * 60 * 1_000;\nconst MS_24_H = 24 * 60 * 60 * 1_000;\n\n/**\n * Returns the next polling interval in ms based on total elapsed time.\n * 0 – 5 min → 15 s\n * 5 – 30 min → 30 s\n * 30 min – ∞ → 60 s\n */\nexport function backoffInterval(elapsedMs: number): number {\n if (elapsedMs < MS_5_MIN) return 15_000;\n if (elapsedMs < MS_30_MIN) return 30_000;\n return 60_000;\n}\n\n/** Resolves after `ms` milliseconds. */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Polls `fetcher` with exponential backoff until `predicate` returns true,\n * then returns the result. Throws {@link EscrowTimeoutError} after 24 hours.\n *\n * @param address - Escrow address used in the timeout error message.\n * @param fetcher - Async function that returns a value or null.\n * @param predicate - Returns true when polling should stop.\n * @param timeoutMs - Maximum total wait time in ms (default: 24 h).\n */\nexport async function pollUntil<T>(\n address: string,\n fetcher: () => Promise<T | null>,\n predicate: (result: T | null) => result is T,\n timeoutMs = MS_24_H,\n): Promise<T> {\n const deadline = Date.now() + timeoutMs;\n\n while (true) {\n const result = await fetcher();\n if (predicate(result)) return result;\n\n const elapsed = Date.now() - (deadline - timeoutMs);\n if (Date.now() >= deadline) {\n throw new EscrowTimeoutError(address);\n }\n\n const interval = backoffInterval(elapsed);\n // Clamp to remaining time so we don't sleep past the deadline\n const remaining = deadline - Date.now();\n await sleep(Math.min(interval, remaining));\n\n if (Date.now() >= deadline) {\n throw new EscrowTimeoutError(address);\n }\n }\n}\n","import { createHash } from \"node:crypto\";\nimport {\n Connection,\n Keypair,\n PublicKey,\n Transaction,\n TransactionInstruction,\n} from \"@solana/web3.js\";\nimport {\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n getAssociatedTokenAddressSync,\n createAssociatedTokenAccountInstruction,\n} from \"@solana/spl-token\";\n\n// ── Discriminator helper ───────────────────────────────────────────────────────\n\nfunction disc(name: string): Buffer {\n return Buffer.from(\n createHash(\"sha256\").update(`global:${name}`).digest(),\n ).subarray(0, 8);\n}\n\nconst DISC_RELEASE_PAYMENT = disc(\"release_payment\");\n\n// ── Constants ──────────────────────────────────────────────────────────────────\n\nconst PROGRAM_ID = new PublicKey(\"EjLpJ3obUYk1f2KDensU7UdGBZTxSdxufm7CSnMA3H5C\");\n\n/**\n * PlatformConfig account layout (after 8-byte Anchor discriminator):\n * fee_bps : u16 — offset 8..10\n * oracle_authority : Pubkey — offset 10..42\n * usdc_mint : Pubkey — offset 42..74\n * treasury : Pubkey — offset 74..106\n */\nexport async function fetchPlatformConfig(\n connection: Connection,\n): Promise<{ mint: PublicKey; treasury: PublicKey }> {\n const [pda] = PublicKey.findProgramAddressSync([Buffer.from(\"config\")], PROGRAM_ID);\n const info = await connection.getAccountInfo(pda);\n if (!info) throw new Error(\"PlatformConfig account not found on-chain\");\n return {\n mint: new PublicKey(info.data.slice(42, 74)),\n treasury: new PublicKey(info.data.slice(74, 106)),\n };\n}\n\n// ── Sign and submit ────────────────────────────────────────────────────────────\n\n/**\n * Decode a base64 unsigned transaction, sign it with `wallet`, submit to Solana,\n * and return the transaction signature.\n */\nexport async function signAndSend(\n base64Tx: string,\n wallet: Keypair,\n connection: Connection,\n): Promise<string> {\n const buf = Buffer.from(base64Tx, \"base64\");\n const tx = Transaction.from(buf);\n tx.partialSign(wallet);\n const raw = tx.serialize();\n const signature = await connection.sendRawTransaction(raw, {\n skipPreflight: false,\n });\n await connection.confirmTransaction(signature, \"confirmed\");\n return signature;\n}\n\n// ── release_payment transaction builder ───────────────────────────────────────\n\n/**\n * Build an unsigned `release_payment` transaction.\n * The buyer signs to approve payment to the assigned worker.\n *\n * Account order (matches the on-chain `ReleasePayment` context):\n * 0. buyer — Signer, writable\n * 1. platform_config — read\n * 2. mint — read\n * 3. escrow_account — writable\n * 4. vault — ATA(mint, escrowPda), writable\n * 5. worker_ata — ATA(mint, worker), writable\n * 6. treasury_ata — ATA(mint, treasury), writable\n * 7. worker — read\n * 8. treasury — read\n * 9. token_program — read\n * 10. associated_token_program — read\n */\nexport async function buildReleasePaymentTx(params: {\n buyer: PublicKey;\n escrowPda: PublicKey;\n worker: PublicKey;\n mint: PublicKey;\n treasury: PublicKey;\n connection: Connection;\n}): Promise<string> {\n const { buyer, escrowPda, worker, mint, treasury, connection } = params;\n\n const [platformConfig] = PublicKey.findProgramAddressSync(\n [Buffer.from(\"config\")],\n PROGRAM_ID,\n );\n const vault = getAssociatedTokenAddressSync(\n mint,\n escrowPda,\n true,\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n );\n const workerAta = getAssociatedTokenAddressSync(\n mint,\n worker,\n false,\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n );\n const treasuryAta = getAssociatedTokenAddressSync(\n mint,\n treasury,\n false,\n TOKEN_PROGRAM_ID,\n ASSOCIATED_TOKEN_PROGRAM_ID,\n );\n\n // Check which ATAs need to be created; the on-chain program has a hard\n // AccountNotInitialized guard (no init_if_needed), so we must ensure both\n // exist before the release_payment instruction runs.\n const [workerAtaInfo, treasuryAtaInfo] = await connection.getMultipleAccountsInfo([\n workerAta,\n treasuryAta,\n ]);\n\n const ix = new TransactionInstruction({\n programId: PROGRAM_ID,\n keys: [\n { pubkey: buyer, isSigner: true, isWritable: true },\n { pubkey: platformConfig, isSigner: false, isWritable: false },\n { pubkey: mint, isSigner: false, isWritable: false },\n { pubkey: escrowPda, isSigner: false, isWritable: true },\n { pubkey: vault, isSigner: false, isWritable: true },\n { pubkey: workerAta, isSigner: false, isWritable: true },\n { pubkey: treasuryAta, isSigner: false, isWritable: true },\n { pubkey: worker, isSigner: false, isWritable: false },\n { pubkey: treasury, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n ],\n data: DISC_RELEASE_PAYMENT,\n });\n\n const { blockhash } = await connection.getLatestBlockhash(\"confirmed\");\n const tx = new Transaction();\n tx.recentBlockhash = blockhash;\n tx.feePayer = buyer;\n\n if (!workerAtaInfo) {\n tx.add(\n createAssociatedTokenAccountInstruction(buyer, workerAta, worker, mint),\n );\n }\n if (!treasuryAtaInfo) {\n tx.add(\n createAssociatedTokenAccountInstruction(buyer, treasuryAta, treasury, mint),\n );\n }\n\n tx.add(ix);\n return tx.serialize({ requireAllSignatures: false }).toString(\"base64\");\n}\n"],"mappings":"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","names":["Connection","PublicKey","Connection","PublicKey"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@escro/sdk",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "TypeScript SDK for the escro.ai on-chain escrow protocol",
5
5
  "license": "MIT",
6
6
  "repository": {