diff --git a/CHANGELOG.md b/CHANGELOG.md index ca19b9b..80d5135 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to `@fundable/sdk` are documented here. +## 0.2.1 + +### Fixed + +- parse the Fundable backend's `{ status, data }` success envelope across wallet + authentication and sponsorship requests; +- call the browser's native `fetch` with its required global receiver. + ## 0.2.0 Mainnet-readiness integration release. diff --git a/package.json b/package.json index e98afbd..f34f28c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@fundable/sdk", - "version": "0.2.0", + "version": "0.2.1", "private": false, "description": "Multichain TypeScript SDK for Fundable Protocol; Stellar adapter included", "license": "MIT", diff --git a/src/stellar/sponsorship-client.test.ts b/src/stellar/sponsorship-client.test.ts index 305823a..c32cfbc 100644 --- a/src/stellar/sponsorship-client.test.ts +++ b/src/stellar/sponsorship-client.test.ts @@ -9,19 +9,23 @@ function jsonResponse(body: object, status = 200): Response { }); } +function successfulResponse(data: object, status = 200): Response { + return jsonResponse({ status: true, data }, status); +} + describe("StellarSponsorshipClient", () => { it("authenticates a wallet and uses the bearer session for sponsorship", async () => { const fetcher = vi .fn() .mockResolvedValueOnce( - jsonResponse({ + successfulResponse({ challenge_id: "challenge-id", message: "Sign this Fundable challenge", expires_at: "2030-01-01T00:00:00.000Z", }), ) .mockResolvedValueOnce( - jsonResponse({ + successfulResponse({ access_token: "session-token", token_type: "Bearer", expires_at: "2030-01-01T00:15:00.000Z", @@ -29,7 +33,7 @@ describe("StellarSponsorshipClient", () => { }), ) .mockResolvedValueOnce( - jsonResponse({ + successfulResponse({ fee_token: "CFEE", fee_in_token: "123", fee_in_token_ui: "0.0000123", @@ -66,7 +70,7 @@ describe("StellarSponsorshipClient", () => { const fetcher = vi .fn() .mockResolvedValueOnce( - jsonResponse({ + successfulResponse({ transaction_xdr: "built-xdr", user_auth_entry: "auth-entry", fee_token: "CFEE", @@ -79,7 +83,7 @@ describe("StellarSponsorshipClient", () => { }), ) .mockResolvedValueOnce( - jsonResponse({ + successfulResponse({ intentId: "intent-1", submissionId: "submission-1", status: "pending", @@ -121,6 +125,26 @@ describe("StellarSponsorshipClient", () => { ); }); + it("keeps compatibility with unwrapped successful responses", async () => { + const fetcher = vi.fn().mockResolvedValueOnce( + jsonResponse({ + challenge_id: "challenge-id", + message: "Sign this Fundable challenge", + expires_at: "2030-01-01T00:00:00.000Z", + }), + ); + const client = new StellarSponsorshipClient({ + backendUrl: "https://api.example.com", + fetch: fetcher, + }); + + await expect(client.createChallenge("GACCOUNT", "TESTNET")).resolves.toEqual({ + challengeId: "challenge-id", + message: "Sign this Fundable challenge", + expiresAt: "2030-01-01T00:00:00.000Z", + }); + }); + it("rejects expired builds before calling the backend", async () => { const fetcher = vi.fn(); const client = new StellarSponsorshipClient({ diff --git a/src/stellar/sponsorship-client.ts b/src/stellar/sponsorship-client.ts index 14dd5cf..a471b9e 100644 --- a/src/stellar/sponsorship-client.ts +++ b/src/stellar/sponsorship-client.ts @@ -142,6 +142,13 @@ function optionalString(value: unknown): string | null { return typeof value === "string" && value.trim() ? value : null; } +function unwrapResponseData(payload: Record): Record { + const data = payload.data; + return payload.status === true && data !== null && typeof data === "object" && !Array.isArray(data) + ? data + : payload; +} + export class StellarSponsorshipClient { private readonly fetcher: typeof fetch; private readonly backendUrl: string; @@ -159,7 +166,7 @@ export class StellarSponsorshipClient { this.backendUrl = config.backendUrl.replace(/\/$/, ""); this.accessToken = config.accessToken; this.headers = config.headers ?? {}; - this.fetcher = config.fetch ?? fetch; + this.fetcher = config.fetch ?? ((input, init) => globalThis.fetch(input, init)); } setAccessToken(accessToken: string | undefined): void { @@ -331,6 +338,6 @@ export class StellarSponsorshipClient { chain: "stellar", }); } - return payload; + return unwrapResponseData(payload); } }