@yallet/rwa-sdk 0.2.0
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/README.md +365 -0
- package/dist/credential-nft-server.d.ts +75 -0
- package/dist/credential-nft-server.d.ts.map +1 -0
- package/dist/credential-nft-server.js +122 -0
- package/dist/credential-nft-server.js.map +1 -0
- package/dist/credential-nft.d.ts +31 -0
- package/dist/credential-nft.d.ts.map +1 -0
- package/dist/credential-nft.js +38 -0
- package/dist/credential-nft.js.map +1 -0
- package/dist/encryption.d.ts +107 -0
- package/dist/encryption.d.ts.map +1 -0
- package/dist/encryption.js +176 -0
- package/dist/encryption.js.map +1 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +66 -0
- package/dist/index.js.map +1 -0
- package/dist/metadata.d.ts +161 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +180 -0
- package/dist/metadata.js.map +1 -0
- package/dist/minting.d.ts +63 -0
- package/dist/minting.d.ts.map +1 -0
- package/dist/minting.js +194 -0
- package/dist/minting.js.map +1 -0
- package/dist/payloads.d.ts +120 -0
- package/dist/payloads.d.ts.map +1 -0
- package/dist/payloads.js +118 -0
- package/dist/payloads.js.map +1 -0
- package/dist/registry.d.ts +77 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +173 -0
- package/dist/registry.js.map +1 -0
- package/dist/sdk.d.ts +158 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/sdk.js +346 -0
- package/dist/sdk.js.map +1 -0
- package/dist/storage.d.ts +80 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +284 -0
- package/dist/storage.js.map +1 -0
- package/dist/types.d.ts +278 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/package.json +64 -0
- package/src/credential-nft-server.ts +201 -0
- package/src/credential-nft.ts +64 -0
- package/src/encryption.ts +308 -0
- package/src/index.ts +151 -0
- package/src/metadata.ts +336 -0
- package/src/minting.ts +266 -0
- package/src/payloads.ts +238 -0
- package/src/registry.ts +236 -0
- package/src/sdk.ts +507 -0
- package/src/storage.ts +364 -0
- package/src/types.ts +318 -0
- package/wasm/README.md +33 -0
package/src/sdk.ts
ADDED
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yallet RWA SDK - Main SDK Class
|
|
3
|
+
*
|
|
4
|
+
* High-level interface for minting encrypted RWA assets as Solana cNFTs
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type {
|
|
8
|
+
SDKConfig,
|
|
9
|
+
MintRequest,
|
|
10
|
+
MintResult,
|
|
11
|
+
RegisteredUser,
|
|
12
|
+
UserRegistry,
|
|
13
|
+
InvoiceData,
|
|
14
|
+
NoteData,
|
|
15
|
+
FileData,
|
|
16
|
+
PhotoData,
|
|
17
|
+
EncryptFunction,
|
|
18
|
+
TreeConfig,
|
|
19
|
+
Signer,
|
|
20
|
+
} from './types.js';
|
|
21
|
+
import { AssetType } from './types.js';
|
|
22
|
+
import { ECIESEncryptor, createWasmEncryptor, encryptAsset } from './encryption.js';
|
|
23
|
+
import {
|
|
24
|
+
buildInvoicePayload,
|
|
25
|
+
buildFilePayload,
|
|
26
|
+
buildMessagePayload,
|
|
27
|
+
buildPhotoPayload,
|
|
28
|
+
} from './payloads.js';
|
|
29
|
+
import { uploadEncryptedAsset, uploadMetadata, type UploadOptions } from './storage.js';
|
|
30
|
+
import { generateNFTMetadata, generateInvoiceMetadata } from './metadata.js';
|
|
31
|
+
import { CNFTMinter, createMinter } from './minting.js';
|
|
32
|
+
import { InMemoryRegistry, createRegistry, type RegistryOptions } from './registry.js';
|
|
33
|
+
import type { Keypair } from '@metaplex-foundation/umi';
|
|
34
|
+
|
|
35
|
+
// ======================================
|
|
36
|
+
// RWA SDK Class
|
|
37
|
+
// ======================================
|
|
38
|
+
|
|
39
|
+
export class YalletRWASDK {
|
|
40
|
+
private config: SDKConfig;
|
|
41
|
+
private registry: UserRegistry;
|
|
42
|
+
private minter: CNFTMinter;
|
|
43
|
+
private encryptor: ECIESEncryptor | ReturnType<typeof createWasmEncryptor>;
|
|
44
|
+
private uploadOptions: UploadOptions;
|
|
45
|
+
|
|
46
|
+
constructor(
|
|
47
|
+
config: SDKConfig,
|
|
48
|
+
options: {
|
|
49
|
+
registry?: UserRegistry | RegistryOptions;
|
|
50
|
+
wasmEncryptFn?: EncryptFunction;
|
|
51
|
+
uploadOptions?: UploadOptions;
|
|
52
|
+
} = {}
|
|
53
|
+
) {
|
|
54
|
+
this.config = config;
|
|
55
|
+
|
|
56
|
+
// Initialize registry
|
|
57
|
+
if (options.registry) {
|
|
58
|
+
if ('getUser' in options.registry) {
|
|
59
|
+
this.registry = options.registry;
|
|
60
|
+
} else {
|
|
61
|
+
this.registry = createRegistry(options.registry);
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
this.registry = new InMemoryRegistry();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Initialize encryptor
|
|
68
|
+
if (options.wasmEncryptFn) {
|
|
69
|
+
this.encryptor = createWasmEncryptor(options.wasmEncryptFn);
|
|
70
|
+
} else {
|
|
71
|
+
this.encryptor = new ECIESEncryptor();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Initialize minter
|
|
75
|
+
this.minter = createMinter(config);
|
|
76
|
+
|
|
77
|
+
// Upload options
|
|
78
|
+
this.uploadOptions = {
|
|
79
|
+
network: config.network,
|
|
80
|
+
apiKey: config.arweaveApiKey,
|
|
81
|
+
endpoint: config.arweaveEndpoint,
|
|
82
|
+
...options.uploadOptions,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ======================================
|
|
87
|
+
// Configuration
|
|
88
|
+
// ======================================
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Set the signer for minting transactions
|
|
92
|
+
*
|
|
93
|
+
* @param keypair - Umi keypair for signing
|
|
94
|
+
*/
|
|
95
|
+
setSigner(keypair: Keypair): void {
|
|
96
|
+
this.minter.setSigner(keypair);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Set the Merkle tree configuration
|
|
101
|
+
*
|
|
102
|
+
* @param treeConfig - Tree configuration
|
|
103
|
+
*/
|
|
104
|
+
setTreeConfig(treeConfig: TreeConfig): void {
|
|
105
|
+
this.minter.setTreeConfig(treeConfig);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Get the user registry
|
|
110
|
+
*/
|
|
111
|
+
getRegistry(): UserRegistry {
|
|
112
|
+
return this.registry;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ======================================
|
|
116
|
+
// User Management
|
|
117
|
+
// ======================================
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Register a user with their xidentity
|
|
121
|
+
*
|
|
122
|
+
* @param user - User to register
|
|
123
|
+
*/
|
|
124
|
+
async registerUser(user: RegisteredUser): Promise<void> {
|
|
125
|
+
await this.registry.registerUser(user);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Get a registered user by Solana address
|
|
130
|
+
*
|
|
131
|
+
* @param solanaAddress - User's Solana address
|
|
132
|
+
* @returns Registered user or null
|
|
133
|
+
*/
|
|
134
|
+
async getUser(solanaAddress: string): Promise<RegisteredUser | null> {
|
|
135
|
+
return this.registry.getUser(solanaAddress);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ======================================
|
|
139
|
+
// Minting Methods
|
|
140
|
+
// ======================================
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Mint an encrypted invoice to a recipient.
|
|
144
|
+
* Uses extension-compatible payload (invoice bundle) so the recipient's wallet can decrypt and display.
|
|
145
|
+
*
|
|
146
|
+
* @param invoice - Invoice data
|
|
147
|
+
* @param recipientAddress - Recipient's Solana address
|
|
148
|
+
* @param options - Name, description, and optional pdf/sender/recipient for extension compatibility
|
|
149
|
+
* @returns Mint result
|
|
150
|
+
*/
|
|
151
|
+
async mintInvoice(
|
|
152
|
+
invoice: InvoiceData,
|
|
153
|
+
recipientAddress: string,
|
|
154
|
+
options: {
|
|
155
|
+
name?: string;
|
|
156
|
+
description?: string;
|
|
157
|
+
pdfBase64?: string;
|
|
158
|
+
senderProfile?: Record<string, unknown>;
|
|
159
|
+
recipientProfile?: Record<string, unknown>;
|
|
160
|
+
uuid?: string;
|
|
161
|
+
} = {}
|
|
162
|
+
): Promise<MintResult> {
|
|
163
|
+
const bundle = buildInvoicePayload(invoice, {
|
|
164
|
+
uuid: options.uuid,
|
|
165
|
+
pdfBase64: options.pdfBase64,
|
|
166
|
+
senderProfile: options.senderProfile,
|
|
167
|
+
recipientProfile: options.recipientProfile,
|
|
168
|
+
});
|
|
169
|
+
return this.mint({
|
|
170
|
+
assetType: AssetType.INVOICE,
|
|
171
|
+
assetData: bundle as unknown as InvoiceData,
|
|
172
|
+
recipientAddress,
|
|
173
|
+
name: options.name || `Invoice #${invoice.invoiceId}`,
|
|
174
|
+
description: options.description,
|
|
175
|
+
uuid: options.uuid,
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Mint an encrypted file to a recipient (extension-compatible payload).
|
|
181
|
+
*/
|
|
182
|
+
async mintFile(
|
|
183
|
+
file: FileData,
|
|
184
|
+
recipientAddress: string,
|
|
185
|
+
options: { name?: string; description?: string; uuid?: string } = {}
|
|
186
|
+
): Promise<MintResult> {
|
|
187
|
+
const payload = buildFilePayload(file, { id: options.uuid });
|
|
188
|
+
return this.mint({
|
|
189
|
+
assetType: AssetType.FILE,
|
|
190
|
+
assetData: payload as unknown as FileData,
|
|
191
|
+
recipientAddress,
|
|
192
|
+
name: options.name || file.filename,
|
|
193
|
+
description: options.description,
|
|
194
|
+
uuid: options.uuid,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Mint an encrypted message/note to a recipient (extension-compatible payload, type always 'sent').
|
|
200
|
+
*/
|
|
201
|
+
async mintMessage(
|
|
202
|
+
note: NoteData,
|
|
203
|
+
recipientAddress: string,
|
|
204
|
+
options: {
|
|
205
|
+
name?: string;
|
|
206
|
+
description?: string;
|
|
207
|
+
uuid?: string;
|
|
208
|
+
recipientId?: string | null;
|
|
209
|
+
recipientName?: string | null;
|
|
210
|
+
replyTo?: string | null;
|
|
211
|
+
} = {}
|
|
212
|
+
): Promise<MintResult> {
|
|
213
|
+
const payload = buildMessagePayload(note, {
|
|
214
|
+
uuid: options.uuid,
|
|
215
|
+
recipientId: options.recipientId,
|
|
216
|
+
recipientName: options.recipientName,
|
|
217
|
+
replyTo: options.replyTo,
|
|
218
|
+
});
|
|
219
|
+
return this.mint({
|
|
220
|
+
assetType: AssetType.NOTE,
|
|
221
|
+
assetData: payload as unknown as NoteData,
|
|
222
|
+
recipientAddress,
|
|
223
|
+
name: options.name || note.title,
|
|
224
|
+
description: options.description,
|
|
225
|
+
uuid: options.uuid,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Mint an encrypted picture/photo to a recipient (extension-compatible payload).
|
|
231
|
+
*/
|
|
232
|
+
async mintPhoto(
|
|
233
|
+
photo: PhotoData,
|
|
234
|
+
recipientAddress: string,
|
|
235
|
+
options: { name?: string; description?: string; uuid?: string; thumbnail?: string } = {}
|
|
236
|
+
): Promise<MintResult> {
|
|
237
|
+
const payload = buildPhotoPayload(photo, {
|
|
238
|
+
id: options.uuid,
|
|
239
|
+
thumbnail: options.thumbnail,
|
|
240
|
+
});
|
|
241
|
+
return this.mint({
|
|
242
|
+
assetType: AssetType.PHOTO,
|
|
243
|
+
assetData: payload as unknown as PhotoData,
|
|
244
|
+
recipientAddress,
|
|
245
|
+
name: options.name || photo.filename,
|
|
246
|
+
description: options.description,
|
|
247
|
+
uuid: options.uuid,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Mint an encrypted asset to a recipient
|
|
253
|
+
*
|
|
254
|
+
* This is the main minting method that handles the full flow:
|
|
255
|
+
* 1. Look up recipient's xidentity from registry
|
|
256
|
+
* 2. Encrypt asset with recipient's xidentity
|
|
257
|
+
* 3. Upload encrypted data to Arweave
|
|
258
|
+
* 4. Generate and upload NFT metadata
|
|
259
|
+
* 5. Mint cNFT to recipient
|
|
260
|
+
*
|
|
261
|
+
* @param request - Mint request
|
|
262
|
+
* @returns Mint result
|
|
263
|
+
*/
|
|
264
|
+
async mint(request: MintRequest): Promise<MintResult> {
|
|
265
|
+
const {
|
|
266
|
+
assetType,
|
|
267
|
+
assetData,
|
|
268
|
+
recipientAddress,
|
|
269
|
+
name,
|
|
270
|
+
description,
|
|
271
|
+
attributes = [],
|
|
272
|
+
// New fields
|
|
273
|
+
uuid,
|
|
274
|
+
previousToken,
|
|
275
|
+
schema,
|
|
276
|
+
mimeType,
|
|
277
|
+
dataSize,
|
|
278
|
+
} = request;
|
|
279
|
+
|
|
280
|
+
try {
|
|
281
|
+
// 1. Look up recipient's xidentity
|
|
282
|
+
const recipient = await this.registry.getUser(recipientAddress);
|
|
283
|
+
|
|
284
|
+
if (!recipient) {
|
|
285
|
+
return {
|
|
286
|
+
success: false,
|
|
287
|
+
error: `Recipient not registered: ${recipientAddress}. User must register their xidentity first.`,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
console.log(`[RWA SDK] Minting ${assetType} to ${recipientAddress}`);
|
|
292
|
+
|
|
293
|
+
// 2. Encrypt asset with recipient's xidentity
|
|
294
|
+
console.log('[RWA SDK] Encrypting asset...');
|
|
295
|
+
const encryptedPayload = await encryptAsset(
|
|
296
|
+
assetData,
|
|
297
|
+
assetType,
|
|
298
|
+
recipient.xidentity,
|
|
299
|
+
this.encryptor,
|
|
300
|
+
{ uuid, previousToken, schema }
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
// 3. Upload encrypted data to Arweave
|
|
304
|
+
console.log('[RWA SDK] Uploading encrypted data to Arweave...');
|
|
305
|
+
const dataUploadResult = await uploadEncryptedAsset(
|
|
306
|
+
encryptedPayload,
|
|
307
|
+
{
|
|
308
|
+
assetType,
|
|
309
|
+
direction: 'received',
|
|
310
|
+
network: this.config.network,
|
|
311
|
+
},
|
|
312
|
+
this.uploadOptions
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
console.log('[RWA SDK] Encrypted data uploaded:', dataUploadResult.id);
|
|
316
|
+
|
|
317
|
+
// 4. Generate NFT metadata with new fields
|
|
318
|
+
const nftMetadata = generateNFTMetadata({
|
|
319
|
+
name,
|
|
320
|
+
description,
|
|
321
|
+
assetType,
|
|
322
|
+
encryptedDataUri: dataUploadResult.arweaveUri,
|
|
323
|
+
owner: recipientAddress,
|
|
324
|
+
direction: 'received',
|
|
325
|
+
additionalAttributes: attributes,
|
|
326
|
+
// New fields from encryption result
|
|
327
|
+
uuid: encryptedPayload.uuid,
|
|
328
|
+
timestamp: Math.floor(encryptedPayload.timestamp / 1000), // Convert to seconds
|
|
329
|
+
previousToken,
|
|
330
|
+
schema,
|
|
331
|
+
mimeType,
|
|
332
|
+
dataSize: dataSize || encryptedPayload.dataSize,
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
// 5. Upload metadata to Arweave
|
|
336
|
+
console.log('[RWA SDK] Uploading metadata to Arweave...');
|
|
337
|
+
const metadataUploadResult = await uploadMetadata(
|
|
338
|
+
nftMetadata as unknown as Record<string, unknown>,
|
|
339
|
+
this.uploadOptions
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
console.log('[RWA SDK] Metadata uploaded:', metadataUploadResult.id);
|
|
343
|
+
|
|
344
|
+
// 6. Mint cNFT
|
|
345
|
+
console.log('[RWA SDK] Minting cNFT...');
|
|
346
|
+
const mintResult = await this.minter.mint({
|
|
347
|
+
metadataUri: metadataUploadResult.arweaveUri,
|
|
348
|
+
name,
|
|
349
|
+
recipient: recipientAddress,
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
if (!mintResult.success) {
|
|
353
|
+
return { ...mintResult, uuid: encryptedPayload.uuid };
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
console.log('[RWA SDK] cNFT minted successfully!');
|
|
357
|
+
|
|
358
|
+
return {
|
|
359
|
+
success: true,
|
|
360
|
+
assetId: mintResult.assetId,
|
|
361
|
+
signature: mintResult.signature,
|
|
362
|
+
arweaveTxId: dataUploadResult.id,
|
|
363
|
+
metadataArweaveTxId: metadataUploadResult.id,
|
|
364
|
+
uuid: encryptedPayload.uuid,
|
|
365
|
+
};
|
|
366
|
+
} catch (err) {
|
|
367
|
+
const errorMessage = err instanceof Error ? err.message : 'Unknown error';
|
|
368
|
+
console.error('[RWA SDK] Minting failed:', errorMessage);
|
|
369
|
+
|
|
370
|
+
return {
|
|
371
|
+
success: false,
|
|
372
|
+
error: errorMessage,
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// ======================================
|
|
378
|
+
// Batch Minting
|
|
379
|
+
// ======================================
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Mint multiple invoices to different recipients
|
|
383
|
+
*
|
|
384
|
+
* @param invoices - Array of invoice requests
|
|
385
|
+
* @returns Array of mint results
|
|
386
|
+
*/
|
|
387
|
+
async mintInvoiceBatch(
|
|
388
|
+
invoices: Array<{
|
|
389
|
+
invoice: InvoiceData;
|
|
390
|
+
recipientAddress: string;
|
|
391
|
+
name?: string;
|
|
392
|
+
}>
|
|
393
|
+
): Promise<MintResult[]> {
|
|
394
|
+
const results: MintResult[] = [];
|
|
395
|
+
|
|
396
|
+
for (const item of invoices) {
|
|
397
|
+
const result = await this.mintInvoice(
|
|
398
|
+
item.invoice,
|
|
399
|
+
item.recipientAddress,
|
|
400
|
+
{ name: item.name }
|
|
401
|
+
);
|
|
402
|
+
results.push(result);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
return results;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// ======================================
|
|
409
|
+
// Utility Methods
|
|
410
|
+
// ======================================
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Check if a user is registered
|
|
414
|
+
*
|
|
415
|
+
* @param solanaAddress - User's Solana address
|
|
416
|
+
* @returns true if registered
|
|
417
|
+
*/
|
|
418
|
+
async isUserRegistered(solanaAddress: string): Promise<boolean> {
|
|
419
|
+
const user = await this.registry.getUser(solanaAddress);
|
|
420
|
+
return user !== null;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Get the current tree configuration
|
|
425
|
+
*/
|
|
426
|
+
async getTreeConfig(): Promise<TreeConfig | null> {
|
|
427
|
+
return this.minter.getTreeConfig();
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Encrypt and upload without minting
|
|
432
|
+
* Useful for testing or when you want to handle minting separately
|
|
433
|
+
*
|
|
434
|
+
* @param assetData - Asset data to encrypt
|
|
435
|
+
* @param assetType - Type of asset
|
|
436
|
+
* @param recipientXidentity - Recipient's xidentity (base64)
|
|
437
|
+
* @returns Upload results
|
|
438
|
+
*/
|
|
439
|
+
async encryptAndUpload(
|
|
440
|
+
assetData: unknown,
|
|
441
|
+
assetType: AssetType,
|
|
442
|
+
recipientXidentity: string
|
|
443
|
+
): Promise<{
|
|
444
|
+
encryptedDataUri: string;
|
|
445
|
+
metadataUri: string;
|
|
446
|
+
}> {
|
|
447
|
+
// Encrypt
|
|
448
|
+
const encryptedPayload = await encryptAsset(
|
|
449
|
+
assetData,
|
|
450
|
+
assetType,
|
|
451
|
+
recipientXidentity,
|
|
452
|
+
this.encryptor
|
|
453
|
+
);
|
|
454
|
+
|
|
455
|
+
// Upload encrypted data
|
|
456
|
+
const dataUploadResult = await uploadEncryptedAsset(
|
|
457
|
+
encryptedPayload,
|
|
458
|
+
{
|
|
459
|
+
assetType,
|
|
460
|
+
direction: 'received',
|
|
461
|
+
network: this.config.network,
|
|
462
|
+
},
|
|
463
|
+
this.uploadOptions
|
|
464
|
+
);
|
|
465
|
+
|
|
466
|
+
// Generate and upload metadata
|
|
467
|
+
const nftMetadata = generateNFTMetadata({
|
|
468
|
+
name: `Encrypted ${assetType}`,
|
|
469
|
+
assetType,
|
|
470
|
+
encryptedDataUri: dataUploadResult.arweaveUri,
|
|
471
|
+
owner: 'pending', // Will be set during minting
|
|
472
|
+
direction: 'received',
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
const metadataUploadResult = await uploadMetadata(
|
|
476
|
+
nftMetadata as unknown as Record<string, unknown>,
|
|
477
|
+
this.uploadOptions
|
|
478
|
+
);
|
|
479
|
+
|
|
480
|
+
return {
|
|
481
|
+
encryptedDataUri: dataUploadResult.arweaveUri,
|
|
482
|
+
metadataUri: metadataUploadResult.arweaveUri,
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// ======================================
|
|
488
|
+
// Factory Function
|
|
489
|
+
// ======================================
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Create a new RWA SDK instance
|
|
493
|
+
*
|
|
494
|
+
* @param config - SDK configuration
|
|
495
|
+
* @param options - Additional options
|
|
496
|
+
* @returns YalletRWASDK instance
|
|
497
|
+
*/
|
|
498
|
+
export function createRWASDK(
|
|
499
|
+
config: SDKConfig,
|
|
500
|
+
options?: {
|
|
501
|
+
registry?: UserRegistry | RegistryOptions;
|
|
502
|
+
wasmEncryptFn?: EncryptFunction;
|
|
503
|
+
uploadOptions?: UploadOptions;
|
|
504
|
+
}
|
|
505
|
+
): YalletRWASDK {
|
|
506
|
+
return new YalletRWASDK(config, options);
|
|
507
|
+
}
|