Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/sdk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
env:
CARGO_TERM_COLOR: always
PUZZLE_PK: ${{ secrets.PUZZLE_PK }}
RECORD_SCANNER_URL: ${{ secrets.RECORD_SCANNER_URL }}


jobs:
Expand Down
16 changes: 16 additions & 0 deletions sdk/src/models/record-scanner/encryptedRecordsResult.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { RecordScannerErrorBody } from "./error.js";
import type { EncryptedRecord } from "../record-provider/encryptedRecord.js";

export interface EncryptedRecordsSuccess {
ok: true;
data: EncryptedRecord[];
}

export interface EncryptedRecordsFailure {
ok: false;
status: number;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new result types seem to use status: number but the SDK convention (per provingResponse.ts and others) is status: bigint | number. Should we align with the existing pattern for consistency or is this difference intentional?

error: RecordScannerErrorBody;
}

export type EncryptedRecordsResult = EncryptedRecordsSuccess | EncryptedRecordsFailure;

8 changes: 8 additions & 0 deletions sdk/src/models/record-scanner/encryptedRegistrationRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Payload for the /register/encrypted record scanner endpoint.
* Contains the ephemeral key id and the sealed ciphertext of the registration request.
*/
export interface EncryptedRegistrationRequest {
key_id: string;
ciphertext: string;
}
39 changes: 39 additions & 0 deletions sdk/src/models/record-scanner/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { OwnedFilter } from "./ownedFilter";

/**
* Error thrown when a record scanner request fails (e.g. /register, /register/encrypted).
* Includes HTTP status so callers can handle 422 vs 500 etc.
*/
export class RecordScannerRequestError extends Error {
readonly status: number;

constructor(message: string, status: number) {
super(message);
this.name = "RecordScannerRequestError";
this.status = status;
Object.setPrototypeOf(this, RecordScannerRequestError.prototype);
}
}

/** Error thrown when a record scanner request fails due to an invalid response. */
export class UUIDError extends Error {
readonly uuid?: string;
readonly filter?: OwnedFilter;

constructor(message: string, uuid?: string, filter?: OwnedFilter) {
super(message);
this.name = "InvalidResponseError";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we change the name here to "UUIDError" for consistency?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed

this.uuid = uuid;
this.filter = filter;
Object.setPrototypeOf(this, UUIDError.prototype);
}
}

/** General error payload returned from record-scanner endpoints on failure. */
export interface RecordScannerErrorBody {
/** Raw error text returned by the service. */
message: string;
/** HTTP status code from the response. */
status: number;
}

2 changes: 0 additions & 2 deletions sdk/src/models/record-scanner/ownedFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ import { OwnedRecordsResponseFilter } from "./ownedRecordsResponseFilter";
* const ownedFilter: OwnedFilter = {
* unspent: true,
* nonces: ["3077450429259593211617823051143573281856129402760267155982965992208217472983group"],
* decrypt: true,
* filter: {
* program: "credits.aleo",
* record: "credits",
* },
* }
*/
export interface OwnedFilter extends RecordSearchParams {
decrypt?: boolean;
filter?: RecordsFilter;
responseFilter?: OwnedRecordsResponseFilter;
unspent?: boolean;
Expand Down
29 changes: 29 additions & 0 deletions sdk/src/models/record-scanner/ownedRecordsResult.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { RecordScannerErrorBody } from "./error.js";
import type { OwnedRecord } from "../record-provider/ownedRecord.js";

/**
* Success variant of ownedRecords() result.
*
* @property ok - Whether the request was successful, always true for this interface variant.
* @property data - List of owned records corresponding to the filter used.
*/
export interface OwnedRecordsSuccess {
ok: true;
data: OwnedRecord[];
}

/**
* Failure variant of ownedRecords() result.
*
* @property ok - Whether the request was successful, always false for this interface variant.
* @property status - HTTP status code returned by the server.
* @property error - Error payload returned by the server.
*/
export interface OwnedRecordsFailure {
ok: false;
status: number;
error: RecordScannerErrorBody;
}

export type OwnedRecordsResult = OwnedRecordsSuccess | OwnedRecordsFailure;

18 changes: 18 additions & 0 deletions sdk/src/models/record-scanner/registrationResult.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { RegistrationResponse } from "./registrationResponse.js";
import type { RecordScannerErrorBody } from "./error.js";

/** Success variant of registration result. */
export interface RegisterSuccess {
ok: true;
data: RegistrationResponse;
}

/** Failure variant of registration result. */
export interface RegisterFailure {
ok: false;
status: number;
error: RecordScannerErrorBody;
}

/** Result of register() and registerEncrypted(); never throws on HTTP error. */
export type RegisterResult = RegisterSuccess | RegisterFailure;
31 changes: 31 additions & 0 deletions sdk/src/models/record-scanner/serialNumbersResult.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { RecordScannerErrorBody } from "./error.js";

/**
* Success variant of serialNumbers() result.
*
* @property ok - Whether the request was successful, always true for this interface.
* @property data - A map of serial numbers to whether they are owned by the account.
*/
export interface SerialNumbersSuccess {
ok: true;
data: Record<string, boolean>;
}

/**
* Failure variant of serialNumbers() result.
*
* @property ok - Whether the request was successful, always false for this interface.
* @property status - HTTP status code returned by the server.
* @property error - Error payload returned by the server.
*/
export interface SerialNumbersFailure {
ok: false;
status: number;
error: RecordScannerErrorBody;
}

/**
* Success or failure variant of serialNumbers() result.
*/
export type SerialNumbersResult = SerialNumbersSuccess | SerialNumbersFailure;

29 changes: 29 additions & 0 deletions sdk/src/models/record-scanner/statusResult.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { RecordScannerErrorBody } from "./error.js";
import type { StatusResponse } from "./statusResponse.js";

/**
* Success variant of status() result.
*
* @property ok - Whether the request was successful, always true for this interface variant.
* @property data - StatusResponse returned by the server.
*/
export interface StatusSuccess {
ok: true;
data: StatusResponse;
}

/**
* Failure variant of status() result.
*
* @property ok - Whether the request was successful, always false for this interface variant.
* @property status - HTTP status code returned by the server.
* @property error - Error payload returned by the server.
*/
export interface StatusFailure {
ok: false;
status: number;
error: RecordScannerErrorBody;
}

export type StatusResult = StatusSuccess | StatusFailure;

28 changes: 28 additions & 0 deletions sdk/src/models/record-scanner/tagsResult.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { RecordScannerErrorBody } from "./error.js";

/**
* Success variant of tags() result.
*
* @property ok - Whether the request was successful, always true for this interface variant.
* @property data - A map of tags to whether they are owned by the account.
*/
export interface TagsSuccess {
ok: true;
data: Record<string, boolean>;
}

/**
* Failure variant of tags() result.
*
* @property ok - Whether the request was successful, always false for this interface variant.
* @property status - HTTP status code returned by the server.
* @property error - Error payload returned by the server.
*/
export interface TagsFailure {
ok: false;
status: number;
error: RecordScannerErrorBody;
}

export type TagsResult = TagsSuccess | TagsFailure;

14 changes: 12 additions & 2 deletions sdk/src/network-client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { get, post, parseJSON, logAndThrow, retryWithBackoff, environment } from "./utils.js";
import { get, post, parseJSON, logAndThrow, retryWithBackoff, environment, isNode } from "./utils.js";
import { Account } from "./account.js";
import { BlockJSON } from "./models/blockJSON.js";
import { TransactionJSON } from "./models/transaction/transactionJSON.js";
Expand Down Expand Up @@ -1851,6 +1851,7 @@ class AleoNetworkClient {
// Get an ephemeral public key from a DPS service.
const pubKeyResponse = await get(proverUri + "/pubkey", {
headers,
credentials: "include",
});

// Encrypt the provingRequest.
Expand All @@ -1867,10 +1868,19 @@ class AleoNetworkClient {
key_id: pubkey.key_id,
ciphertext: ciphertext,
};

// We're in node, attempt to set the cookie manually.
const cookie = isNode() ? pubKeyResponse.headers.get("set-cookie"): undefined;

// Send the encrypted proving request to the DPS service.
const res = await fetch(`${proverUri}/prove/encrypted`, {
method: "POST",
body: JSON.stringify(payload),
headers,
headers: {
...headers,
...(cookie ? { Cookie: cookie } : {})
},
credentials: "include",
});

// Properly handle the proving response.
Expand Down
1 change: 1 addition & 0 deletions sdk/src/record-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { logAndThrow } from "./utils.js";
import { OwnedRecord } from "./models/record-provider/ownedRecord.js";
import { RecordSearchParams } from "./models/record-provider/recordSearchParams.js";
import { RecordsResponseFilter } from "./models/record-scanner/recordsResponseFilter.js";
import { ViewKey } from "@provablehq/wasm";

/**
* Interface for a record provider. A record provider is used to find records for use in deployment and execution
Expand Down
Loading