Skip to content

Commit 4065cd7

Browse files
wip: started upgrade to record provider interface and started record scanner implementation of said interface
1 parent bceff14 commit 4065cd7

File tree

2 files changed

+346
-23
lines changed

2 files changed

+346
-23
lines changed

sdk/src/record-provider.ts

Lines changed: 117 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,72 @@ import { AleoNetworkClient } from "./network-client.js";
88
* implementations.
99
*/
1010
interface RecordSearchParams {
11+
unspent: boolean;
1112
[key: string]: any; // This allows for arbitrary keys with any type values
1213
}
1314

15+
type RecordsResponseFilter = {
16+
program: boolean;
17+
record: boolean;
18+
function: boolean;
19+
transition: boolean;
20+
blockHeight: boolean;
21+
transactionId: boolean;
22+
transitionId: boolean;
23+
ioIndex: boolean;
24+
}
25+
26+
type EncryptedRecord = {
27+
commitment: string;
28+
checksum?: string;
29+
blockHeight?: number;
30+
programName?: string;
31+
functionName?: string;
32+
outputIndex?: number;
33+
owner?: string;
34+
recordCiphertext?: string;
35+
recordName?: string;
36+
recordNonce?: string;
37+
transactionId?: string;
38+
transitionId?: string;
39+
transactionIndex?: number;
40+
transitionIndex?: number;
41+
}
42+
43+
type OwnedRecord = {
44+
blockHeight?: number;
45+
commitment?: string;
46+
functionName?: string;
47+
outputIndex?: number;
48+
owner?: string;
49+
programName?: string;
50+
recordCiphertext?: string;
51+
recordPlaintext?: string;
52+
recordName?: string;
53+
spent?: boolean;
54+
tag?: string;
55+
transactionId?: string;
56+
transitionId?: string;
57+
transactionIndex?: number;
58+
transitionIndex?: number;
59+
}
60+
61+
interface RecordResponse {
62+
owner?: string;
63+
}
64+
1465
/**
1566
* Interface for a record provider. A record provider is used to find records for use in deployment and execution
1667
* transactions on the Aleo Network. A default implementation is provided by the NetworkRecordProvider class. However,
1768
* a custom implementation can be provided (say if records are synced locally to a database from the network) by
1869
* implementing this interface.
1970
*/
2071
interface RecordProvider {
21-
account: Account
72+
getEncryptedRecords(recordsFilter: RecordSearchParams, responseFilter: RecordsResponseFilter): Promise<EncryptedRecord[]>;
73+
74+
serialNumbersExist(serialNumbers: string[]): Promise<Record<string, boolean>>;
75+
76+
tagsExist(tags: string[]): Promise<Record<string, boolean>>;
2277

2378
/**
2479
* Find a credits.aleo record with a given number of microcredits from the chosen provider
@@ -42,7 +97,7 @@ interface RecordProvider {
4297
* const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
4398
* programManager.transfer(1, "aleo166q6ww6688cug7qxwe7nhctjpymydwzy2h7rscfmatqmfwnjvggqcad0at", "public", 0.5);
4499
*/
45-
findCreditsRecord(microcredits: number, unspent: boolean, nonces?: string[], searchParameters?: RecordSearchParams): Promise<RecordPlaintext>;
100+
findCreditsRecord(microcredits: number, searchParameters: RecordSearchParams, nonces?: string[]): Promise<OwnedRecord>;
46101

47102
/**
48103
* Find a list of credit.aleo records with a given number of microcredits from the chosen provider
@@ -68,7 +123,7 @@ interface RecordProvider {
68123
* const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
69124
* programManager.transfer(1, "aleo166q6ww6688cug7qxwe7nhctjpymydwzy2h7rscfmatqmfwnjvggqcad0at", "public", 0.5);
70125
*/
71-
findCreditsRecords(microcreditAmounts: number[], unspent: boolean, nonces?: string[], searchParameters?: RecordSearchParams): Promise<RecordPlaintext[]>;
126+
findCreditsRecords(microcreditAmounts: number[], searchParameters: RecordSearchParams, nonces?: string[]): Promise<OwnedRecord[]>;
72127

73128
/**
74129
* Find an arbitrary record
@@ -101,7 +156,7 @@ interface RecordProvider {
101156
*
102157
* const record = await recordProvider.findRecord(true, [], params);
103158
*/
104-
findRecord(unspent: boolean, nonces?: string[], searchParameters?: RecordSearchParams): Promise<RecordPlaintext>;
159+
findRecord(searchParameters: RecordSearchParams, filterFn?: (record: RecordPlaintext) => boolean, nonces?: string[]): Promise<OwnedRecord>;
105160

106161
/**
107162
* Find multiple records from arbitrary programs
@@ -135,7 +190,7 @@ interface RecordProvider {
135190
* const params = new CustomRecordSearch(0, 100, 5000, 2, "credits.aleo", "credits");
136191
* const records = await recordProvider.findRecord(true, [], params);
137192
*/
138-
findRecords(unspent: boolean, nonces?: string[], searchParameters?: RecordSearchParams): Promise<RecordPlaintext[]>;
193+
findRecords(searchParameters?: RecordSearchParams, filterFn?: (record: RecordPlaintext) => boolean, nonces?: string[],): Promise<OwnedRecord[]>;
139194
}
140195

141196
/**
@@ -187,7 +242,7 @@ class NetworkRecordProvider implements RecordProvider {
187242
* programManager.transfer(1, "aleo166q6ww6688cug7qxwe7nhctjpymydwzy2h7rscfmatqmfwnjvggqcad0at", "public", 0.5);
188243
*
189244
* */
190-
async findCreditsRecords(microcredits: number[], unspent: boolean, nonces?: string[], searchParameters?: RecordSearchParams): Promise<RecordPlaintext[]> {
245+
async findCreditsRecords(microcredits: number[], searchParameters: RecordSearchParams, nonces?: string[]): Promise<OwnedRecord[]> {
191246
let startHeight = 0;
192247
let endHeight = 0;
193248
let maxAmount = undefined;
@@ -208,10 +263,6 @@ class NetworkRecordProvider implements RecordProvider {
208263
if ("maxAmount" in searchParameters && typeof searchParameters["maxAmount"] == "number") {
209264
maxAmount = searchParameters["maxAmount"];
210265
}
211-
212-
if ("unspent" in searchParameters && typeof searchParameters["unspent"] == "boolean") {
213-
unspent = searchParameters["unspent"]
214-
}
215266
}
216267

217268
// If the end height is not specified, use the current block height
@@ -225,7 +276,15 @@ class NetworkRecordProvider implements RecordProvider {
225276
logAndThrow("Start height must be less than end height");
226277
}
227278

228-
return await this.networkClient.findRecords(startHeight, endHeight, unspent, ["credits.aleo"], microcredits, maxAmount, nonces, this.account.privateKey());
279+
const recordsPts = await this.networkClient.findRecords(startHeight, endHeight, searchParameters.unspent, ["credits.aleo"], microcredits, maxAmount, nonces, this.account.privateKey());
280+
return recordsPts.map((record) => ({
281+
commitment: record.commitment().toString(),
282+
owner: record.owner().toString(),
283+
programName: 'credits.aleo',
284+
recordName: 'credits',
285+
recordPlaintext: record.to_string(),
286+
tag: record.tag().toString(),
287+
}));
229288
}
230289

231290
/**
@@ -255,11 +314,11 @@ class NetworkRecordProvider implements RecordProvider {
255314
* const programManager = new ProgramManager("https://api.explorer.provable.com/v1", keyProvider, recordProvider);
256315
* programManager.transfer(1, "aleo166q6ww6688cug7qxwe7nhctjpymydwzy2h7rscfmatqmfwnjvggqcad0at", "public", 0.5);
257316
*/
258-
async findCreditsRecord(microcredits: number, unspent: boolean, nonces?: string[], searchParameters?: RecordSearchParams): Promise<RecordPlaintext> {
317+
async findCreditsRecord(microcredits: number, searchParameters: RecordSearchParams,nonces?: string[]): Promise<OwnedRecord> {
259318
let records = null;
260319

261320
try {
262-
records = await this.findCreditsRecords([microcredits], unspent, nonces, searchParameters);
321+
records = await this.findCreditsRecords([microcredits], searchParameters, nonces);
263322
} catch (e) {
264323
console.log("No records found with error:", e);
265324
}
@@ -275,14 +334,27 @@ class NetworkRecordProvider implements RecordProvider {
275334
/**
276335
* Find an arbitrary record. WARNING: This function is not implemented yet and will throw an error.
277336
*/
278-
async findRecord(unspent: boolean, nonces?: string[], searchParameters?: RecordSearchParams): Promise<RecordPlaintext> {
279-
throw new Error("Not implemented");
337+
async findRecord(searchParameters: RecordSearchParams, filterFn?: (record: RecordPlaintext) => boolean, nonces?: string[]): Promise<OwnedRecord> {
338+
let records;
339+
340+
try {
341+
records = await this.findRecords(searchParameters, filterFn, nonces);
342+
} catch (e) {
343+
console.log("No records found with error:", e);
344+
}
345+
346+
if (records && records.length > 0) {
347+
return records[0];
348+
}
349+
350+
console.error("Record not found with error:", records);
351+
throw new Error("Record not found");
280352
}
281353

282354
/**
283355
* Find multiple records from a specified program.
284356
*/
285-
async findRecords(unspent: boolean, nonces?: string[], searchParameters?: RecordSearchParams): Promise<RecordPlaintext[]> {
357+
async findRecords(searchParameters: RecordSearchParams, filterFn?: (record: RecordPlaintext) => boolean, nonces?: string[]): Promise<OwnedRecord[]> {
286358
let startHeight = 0;
287359
let endHeight = 0;
288360
let amounts = undefined;
@@ -317,10 +389,6 @@ class NetworkRecordProvider implements RecordProvider {
317389
if ("programs" in searchParameters && Array.isArray(searchParameters["programs"]) && searchParameters["programs"].every((item: any) => typeof item === "string")) {
318390
programs = searchParameters["programs"];
319391
}
320-
321-
if ("unspent" in searchParameters && typeof searchParameters["unspent"] == "boolean") {
322-
unspent = searchParameters["unspent"]
323-
}
324392
}
325393

326394
// If the end height is not specified, use the current block height
@@ -334,9 +402,26 @@ class NetworkRecordProvider implements RecordProvider {
334402
logAndThrow("Start height must be less than end height");
335403
}
336404

337-
return await this.networkClient.findRecords(startHeight, endHeight, unspent, programs, amounts, maxAmount, nonces, this.account.privateKey());
405+
const recordPts = await this.networkClient.findRecords(startHeight, endHeight, searchParameters.unspent, programs, amounts, maxAmount, nonces, this.account.privateKey());
406+
return recordPts.map((record) => ({
407+
commitment: record.commitment().toString(),
408+
owner: record.owner().toString(),
409+
programName: record.program().toString(),
410+
recordName: record.name().toString(),
411+
}));
338412
}
339413

414+
async getEncryptedRecords(recordsFilter: RecordSearchParams, responseFilter: RecordsResponseFilter): Promise<EncryptedRecord[]> {
415+
throw new Error("Not implemented");
416+
}
417+
418+
async serialNumbersExist(serialNumbers: string[]): Promise<Record<string, boolean>> {
419+
throw new Error("Not implemented");
420+
}
421+
422+
async tagsExist(tags: string[]): Promise<Record<string, boolean>> {
423+
throw new Error("Not implemented");
424+
}
340425
}
341426

342427
/**
@@ -360,10 +445,19 @@ class NetworkRecordProvider implements RecordProvider {
360445
class BlockHeightSearch implements RecordSearchParams {
361446
startHeight: number;
362447
endHeight: number;
363-
constructor(startHeight: number, endHeight: number) {
448+
unspent: boolean;
449+
constructor(startHeight: number, endHeight: number, unspent: boolean) {
364450
this.startHeight = startHeight;
365451
this.endHeight = endHeight;
452+
this.unspent = unspent;
366453
}
367454
}
368455

369-
export { BlockHeightSearch, NetworkRecordProvider, RecordProvider, RecordSearchParams};
456+
export {
457+
BlockHeightSearch,
458+
EncryptedRecord,
459+
OwnedRecord,
460+
RecordProvider,
461+
RecordSearchParams,
462+
RecordsResponseFilter,
463+
};

0 commit comments

Comments
 (0)