@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/README.md
ADDED
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
# Yallet RWA SDK
|
|
2
|
+
|
|
3
|
+
SDK for minting encrypted RWA (Real World Assets) as Solana compressed NFTs (cNFTs).
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔐 **End-to-end encryption** using xidentity (X25519) public keys
|
|
8
|
+
- 📦 **Permanent storage** on Arweave via ArDrive Turbo
|
|
9
|
+
- 🌳 **Compressed NFTs** via Metaplex Bubblegum (low cost)
|
|
10
|
+
- 👥 **User registry** for xidentity management
|
|
11
|
+
- 📄 **Multiple asset types**: Invoices, Notes (messages), Files, Photos, Contacts
|
|
12
|
+
- 🔗 **Chrome extension compatible**: Payloads match Yallet extension decrypt format
|
|
13
|
+
- 🧩 **Optional WASM**: Use acegf WASM for encryption (see [wasm/README.md](wasm/README.md))
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @yallet/rwa-sdk
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { createRWASDK, AssetType } from '@yallet/rwa-sdk';
|
|
25
|
+
|
|
26
|
+
// 1. Create SDK instance
|
|
27
|
+
const sdk = createRWASDK({
|
|
28
|
+
rpcEndpoint: 'https://api.mainnet-beta.solana.com',
|
|
29
|
+
network: 'mainnet',
|
|
30
|
+
merkleTreeAddress: 'YOUR_MERKLE_TREE_ADDRESS',
|
|
31
|
+
arweaveApiKey: 'YOUR_ARWEAVE_API_KEY', // Optional for free tier
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// 2. Set up signer (for minting transactions)
|
|
35
|
+
import { keypairIdentity } from '@metaplex-foundation/umi';
|
|
36
|
+
sdk.setSigner(yourKeypair);
|
|
37
|
+
|
|
38
|
+
// 3. Register users with their xidentity
|
|
39
|
+
await sdk.registerUser({
|
|
40
|
+
solanaAddress: 'CUSTOMER_WALLET_ADDRESS',
|
|
41
|
+
xidentity: 'BASE64_XIDENTITY_PUBLIC_KEY', // From Yallet wallet
|
|
42
|
+
name: 'Customer Name',
|
|
43
|
+
registeredAt: Date.now(),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// 4. Mint encrypted invoice
|
|
47
|
+
const result = await sdk.mintInvoice(
|
|
48
|
+
{
|
|
49
|
+
invoiceId: 'INV-2024-001',
|
|
50
|
+
amount: 1500.00,
|
|
51
|
+
currency: 'USD',
|
|
52
|
+
date: new Date().toISOString(),
|
|
53
|
+
dueDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
|
|
54
|
+
items: [
|
|
55
|
+
{ description: 'Consulting Services', quantity: 10, unitPrice: 150, amount: 1500 }
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
'CUSTOMER_WALLET_ADDRESS',
|
|
59
|
+
{ name: 'Invoice #INV-2024-001' }
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
console.log('Minted:', result.assetId);
|
|
63
|
+
console.log('Signature:', result.signature);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Architecture
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
70
|
+
│ Your Application │
|
|
71
|
+
├─────────────────────────────────────────────────────────────┤
|
|
72
|
+
│ Yallet RWA SDK │
|
|
73
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
74
|
+
│ │ Registry │ │ Encryption │ │ Minting │ │
|
|
75
|
+
│ │ (xidentity) │ │ (ECIES) │ │ (Bubblegum) │ │
|
|
76
|
+
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
77
|
+
│ ┌─────────────┐ │
|
|
78
|
+
│ │ Storage │ │
|
|
79
|
+
│ │ (Arweave) │ │
|
|
80
|
+
│ └─────────────┘ │
|
|
81
|
+
├─────────────────────────────────────────────────────────────┤
|
|
82
|
+
│ Solana Blockchain │ Arweave Network │
|
|
83
|
+
│ (cNFT Ownership) │ (Encrypted Data Storage) │
|
|
84
|
+
└─────────────────────────────────────────────────────────────┘
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## User Registration Flow
|
|
88
|
+
|
|
89
|
+
Before minting assets to a user, they must register their xidentity:
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
// User provides their xidentity (from Yallet wallet)
|
|
93
|
+
// The xidentity is a base64-encoded X25519 public key
|
|
94
|
+
|
|
95
|
+
await sdk.registerUser({
|
|
96
|
+
solanaAddress: 'USER_WALLET_ADDRESS',
|
|
97
|
+
xidentity: 'ZzFXyDpLw7GMu3PiPopkM7hHBRWTupjcP7qxSJO2SHU=',
|
|
98
|
+
name: 'John Doe',
|
|
99
|
+
email: 'john@example.com', // Optional
|
|
100
|
+
registeredAt: Date.now(),
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Getting xidentity from Yallet Wallet
|
|
105
|
+
|
|
106
|
+
Users can export their xidentity from Yallet wallet:
|
|
107
|
+
1. Open Yallet → Settings → Export xidentity
|
|
108
|
+
2. The xidentity is safe to share (it's a public key)
|
|
109
|
+
3. Only the wallet owner can decrypt assets encrypted with their xidentity
|
|
110
|
+
|
|
111
|
+
## API Reference
|
|
112
|
+
|
|
113
|
+
### `createRWASDK(config, options?)`
|
|
114
|
+
|
|
115
|
+
Create a new SDK instance.
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
const sdk = createRWASDK({
|
|
119
|
+
// Required
|
|
120
|
+
rpcEndpoint: 'https://api.mainnet-beta.solana.com',
|
|
121
|
+
network: 'mainnet', // or 'devnet'
|
|
122
|
+
|
|
123
|
+
// Merkle Tree (required for minting)
|
|
124
|
+
merkleTreeAddress: 'YOUR_TREE_ADDRESS',
|
|
125
|
+
merkleTreeAuthority: 'TREE_AUTHORITY', // Optional
|
|
126
|
+
|
|
127
|
+
// Arweave (optional)
|
|
128
|
+
arweaveEndpoint: 'https://turbo.irys.xyz',
|
|
129
|
+
arweaveApiKey: 'YOUR_API_KEY',
|
|
130
|
+
|
|
131
|
+
// Backend API (optional, for tree management)
|
|
132
|
+
backendApiUrl: 'https://api.yourdomain.com',
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### `sdk.registerUser(user)`
|
|
137
|
+
|
|
138
|
+
Register a user with their xidentity.
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
await sdk.registerUser({
|
|
142
|
+
solanaAddress: string, // User's Solana wallet address
|
|
143
|
+
xidentity: string, // Base64-encoded X25519 public key
|
|
144
|
+
name?: string, // Display name
|
|
145
|
+
email?: string, // Email address
|
|
146
|
+
metadata?: object, // Custom metadata
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### `sdk.mintInvoice(invoice, recipientAddress, options?)`
|
|
151
|
+
|
|
152
|
+
Mint an encrypted invoice to a registered user (payload matches Yallet extension decrypt format). Optionally pass `pdfBase64`, `senderProfile`, `recipientProfile` for extension display.
|
|
153
|
+
|
|
154
|
+
### `sdk.mintFile(file, recipientAddress, options?)`
|
|
155
|
+
|
|
156
|
+
Mint an encrypted file (FileData: filename, mimeType, content base64, size).
|
|
157
|
+
|
|
158
|
+
### `sdk.mintMessage(note, recipientAddress, options?)`
|
|
159
|
+
|
|
160
|
+
Mint an encrypted message/note (NoteData: title, content), with optional `replyTo`. Payload type is always `sent` (institution sends to users).
|
|
161
|
+
|
|
162
|
+
### `sdk.mintPhoto(photo, recipientAddress, options?)`
|
|
163
|
+
|
|
164
|
+
Mint an encrypted photo (PhotoData: filename, mimeType, content base64).
|
|
165
|
+
|
|
166
|
+
### Example: mintInvoice
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
const result = await sdk.mintInvoice(
|
|
170
|
+
{
|
|
171
|
+
invoiceId: 'INV-001',
|
|
172
|
+
amount: 100.00,
|
|
173
|
+
currency: 'USD',
|
|
174
|
+
date: '2024-01-15T00:00:00Z',
|
|
175
|
+
dueDate: '2024-02-15T00:00:00Z',
|
|
176
|
+
description: 'Monthly subscription',
|
|
177
|
+
items: [
|
|
178
|
+
{ description: 'Service', quantity: 1, unitPrice: 100, amount: 100 }
|
|
179
|
+
],
|
|
180
|
+
},
|
|
181
|
+
'RECIPIENT_ADDRESS',
|
|
182
|
+
{ name: 'Invoice #INV-001', pdfBase64: '...' } // optional PDF
|
|
183
|
+
);
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### `sdk.mint(request)`
|
|
187
|
+
|
|
188
|
+
Mint any asset type.
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
const result = await sdk.mint({
|
|
192
|
+
assetType: AssetType.NOTE,
|
|
193
|
+
assetData: {
|
|
194
|
+
title: 'Meeting Notes',
|
|
195
|
+
content: 'Discussion points...',
|
|
196
|
+
tags: ['meeting', 'project-x'],
|
|
197
|
+
},
|
|
198
|
+
recipientAddress: 'RECIPIENT_ADDRESS',
|
|
199
|
+
name: 'Meeting Notes - Jan 15',
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Asset Types
|
|
204
|
+
|
|
205
|
+
| Type | Description | Data Structure |
|
|
206
|
+
|------|-------------|----------------|
|
|
207
|
+
| `INVOICE` | Invoice | `InvoiceData` |
|
|
208
|
+
| `NOTE` | Message / note | `NoteData` |
|
|
209
|
+
| `FILE` | File | `FileData` |
|
|
210
|
+
| `PHOTO` | Photo | `PhotoData` |
|
|
211
|
+
| `CONTACT` | Contact | `ContactData` |
|
|
212
|
+
|
|
213
|
+
## Payload builders (extension JSON–compatible)
|
|
214
|
+
|
|
215
|
+
To customize the payload before encryption, use the same builder functions the Yallet extension expects:
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
import {
|
|
219
|
+
buildInvoicePayload,
|
|
220
|
+
buildFilePayload,
|
|
221
|
+
buildMessagePayload,
|
|
222
|
+
buildPhotoPayload,
|
|
223
|
+
} from '@yallet/rwa-sdk';
|
|
224
|
+
|
|
225
|
+
const bundle = buildInvoicePayload(invoice, { pdfBase64, senderProfile, recipientProfile });
|
|
226
|
+
const filePayload = buildFilePayload(fileData);
|
|
227
|
+
const notePayload = buildMessagePayload(noteData, { replyTo: previousNftId });
|
|
228
|
+
const photoPayload = buildPhotoPayload(photoData);
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Custom User Registry
|
|
232
|
+
|
|
233
|
+
For production, implement a database-backed registry:
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
import { createRWASDK } from '@yallet/rwa-sdk';
|
|
237
|
+
|
|
238
|
+
const sdk = createRWASDK(config, {
|
|
239
|
+
registry: {
|
|
240
|
+
type: 'http',
|
|
241
|
+
httpConfig: {
|
|
242
|
+
baseUrl: 'https://api.yourdomain.com/registry',
|
|
243
|
+
apiKey: 'YOUR_API_KEY',
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Or implement the `UserRegistry` interface:
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
import type { UserRegistry, RegisteredUser } from '@yallet/rwa-sdk';
|
|
253
|
+
|
|
254
|
+
class MyDatabaseRegistry implements UserRegistry {
|
|
255
|
+
async getUser(solanaAddress: string): Promise<RegisteredUser | null> {
|
|
256
|
+
// Query your database
|
|
257
|
+
}
|
|
258
|
+
async registerUser(user: RegisteredUser): Promise<void> {
|
|
259
|
+
// Insert into database
|
|
260
|
+
}
|
|
261
|
+
// ... other methods
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const sdk = createRWASDK(config, {
|
|
265
|
+
registry: new MyDatabaseRegistry(),
|
|
266
|
+
});
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Server-side Mint (Yault credential NFT)
|
|
270
|
+
|
|
271
|
+
For Yault or other apps that prefer **server-side mint** (no registry, no signer):
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
import { mintCredentialNftViaServer, RWA_UPLOAD_AND_MINT_ENDPOINTS } from '@yallet/rwa-sdk';
|
|
275
|
+
|
|
276
|
+
const result = await mintCredentialNftViaServer(
|
|
277
|
+
recipientSolanaAddress,
|
|
278
|
+
{ user_cred, mnemonic, index, label },
|
|
279
|
+
{
|
|
280
|
+
xidentity: recipientXidentity, // from recipient-addresses API
|
|
281
|
+
dev: true, // use built-in dev endpoint
|
|
282
|
+
uploadAndMintApiUrl: undefined, // override if needed
|
|
283
|
+
network: 'devnet',
|
|
284
|
+
}
|
|
285
|
+
);
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Dev mode
|
|
289
|
+
|
|
290
|
+
When `dev: true` and `uploadAndMintApiUrl` is not set, the SDK uses `RWA_UPLOAD_AND_MINT_ENDPOINTS.dev` (`api.yallet.xyz`). For production, use `dev: false` or pass `uploadAndMintApiUrl` explicitly.
|
|
291
|
+
|
|
292
|
+
## WASM encryption (Yallet extension–compatible)
|
|
293
|
+
|
|
294
|
+
For full compatibility with Yallet extension decryption, use acegf WASM encryption:
|
|
295
|
+
|
|
296
|
+
1. In [acegf-wallet](https://github.com/phaykhe/yallet-chrome), run `wasm-pack build --target web`, then copy the generated `pkg/acegf_bg.wasm` and `pkg/acegf.js` into this SDK's `wasm/` directory (or your deploy path).
|
|
297
|
+
2. In your app, initialize WASM and pass the encrypt function into the SDK:
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
import init from './wasm/acegf.js'; // or your path
|
|
301
|
+
import { createRWASDK, createWasmEncryptor } from '@yallet/rwa-sdk';
|
|
302
|
+
|
|
303
|
+
const acegf = await init(); // optional wasm path: init('/path/to/acegf_bg.wasm')
|
|
304
|
+
const sdk = createRWASDK(config, {
|
|
305
|
+
wasmEncryptFn: createWasmEncryptor(acegf.acegf_encrypt_for_xidentity),
|
|
306
|
+
});
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Without `wasmEncryptFn`, the SDK uses built-in pure JS ECIES; production should use WASM. See [wasm/README.md](wasm/README.md).
|
|
310
|
+
|
|
311
|
+
### Encryption ↔ extension decrypt (inverse)
|
|
312
|
+
|
|
313
|
+
The built-in ECIES in this SDK is aligned with **dev.yallet.chrome-extension** (acegf WASM) so that:
|
|
314
|
+
|
|
315
|
+
- **Encrypt (SDK / Yault):** `shared_secret = ECDH(ephemeral, xidentity)` → `dh_key = SHA256(shared_secret)` → `encrypted_aes_key = AES-GCM(dh_key).encrypt(iv, random_aes_key)` → `encrypted_data = AES-GCM(aes_key).encrypt(iv, plaintext)`. Payload on Arweave: `{ encrypted: { ephemeral_pub, encrypted_aes_key, iv, encrypted_data }, metadata }`.
|
|
316
|
+
- **Decrypt (extension):** `dh_key = SHA256(ECDH(ephemeral_pub, recipient_private))` → `aes_key = AES-GCM(dh_key).decrypt(iv, encrypted_aes_key)` → `plaintext = AES-GCM(aes_key).decrypt(iv, encrypted_data)` → decode base64, optional gzip, then `envelope.data` (e.g. note `{ title, content, metadata }`).
|
|
317
|
+
|
|
318
|
+
Envelope shape: `{ version, type, timestamp, uuid, schema?, previousToken?, data: asset }`. The extension expects `envelope.data` to have e.g. `title` and `content` for notes. Server-side credential mint uses the same envelope and note shape so the extension can decrypt and show the note.
|
|
319
|
+
|
|
320
|
+
## Merkle Tree Setup
|
|
321
|
+
|
|
322
|
+
Before minting, you need a Merkle tree. Create one using Metaplex:
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
import { createTree } from '@metaplex-foundation/mpl-bubblegum';
|
|
326
|
+
|
|
327
|
+
const { tree } = await createTree(umi, {
|
|
328
|
+
maxDepth: 14, // 16,384 NFTs capacity
|
|
329
|
+
maxBufferSize: 64,
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
sdk.setTreeConfig({
|
|
333
|
+
treeAddress: tree.publicKey,
|
|
334
|
+
treeAuthority: umi.identity.publicKey,
|
|
335
|
+
maxDepth: 14,
|
|
336
|
+
capacity: 16384,
|
|
337
|
+
used: 0,
|
|
338
|
+
remaining: 16384,
|
|
339
|
+
usagePercent: 0,
|
|
340
|
+
});
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## Error Handling
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
const result = await sdk.mintInvoice(invoice, recipientAddress);
|
|
347
|
+
|
|
348
|
+
if (!result.success) {
|
|
349
|
+
console.error('Minting failed:', result.error);
|
|
350
|
+
// Handle error
|
|
351
|
+
} else {
|
|
352
|
+
console.log('Success! Asset ID:', result.assetId);
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## License
|
|
357
|
+
|
|
358
|
+
MIT
|
|
359
|
+
|
|
360
|
+
## Links
|
|
361
|
+
|
|
362
|
+
- [Yallet Wallet](https://yallet.app)
|
|
363
|
+
- [Metaplex Bubblegum](https://developers.metaplex.com/bubblegum)
|
|
364
|
+
- [ArDrive Turbo (Arweave)](https://docs.ardrive.io/docs/turbo/turbo-sdk/)
|
|
365
|
+
- [Arweave](https://docs.arweave.org/)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yault credential NFT — server-side mint flow.
|
|
3
|
+
*
|
|
4
|
+
* Encrypts credential payload locally with recipient's xidentity, then POSTs
|
|
5
|
+
* to upload-and-mint API. No registry, signer, or client-side mint needed.
|
|
6
|
+
*/
|
|
7
|
+
/** Payload shape agreed with Yault webapp */
|
|
8
|
+
export interface CredentialNftPayload {
|
|
9
|
+
user_cred: string;
|
|
10
|
+
mnemonic?: string | null;
|
|
11
|
+
index: number;
|
|
12
|
+
label: string;
|
|
13
|
+
/** Optional memo (e.g. "letter to future heirs") — encrypted together with credential, delivered when release triggers. */
|
|
14
|
+
memo?: string | null;
|
|
15
|
+
}
|
|
16
|
+
/** Result shape expected by Yault */
|
|
17
|
+
export interface CredentialMintResult {
|
|
18
|
+
success: boolean;
|
|
19
|
+
txId?: string;
|
|
20
|
+
error?: string;
|
|
21
|
+
}
|
|
22
|
+
/** Options for server-side mint */
|
|
23
|
+
export interface MintCredentialNftViaServerOptions {
|
|
24
|
+
/** Recipient's xidentity (base64). Required. */
|
|
25
|
+
xidentity: string;
|
|
26
|
+
/** Upload-and-mint API URL. If omitted, uses built-in prod/dev endpoint. */
|
|
27
|
+
uploadAndMintApiUrl?: string;
|
|
28
|
+
/** When true, uses built-in dev endpoint (if uploadAndMintApiUrl not set). */
|
|
29
|
+
dev?: boolean;
|
|
30
|
+
/** Optional: custom headers (e.g. Authorization) for the API request */
|
|
31
|
+
headers?: Record<string, string>;
|
|
32
|
+
/** Network for mint (mainnet | devnet). Default: mainnet */
|
|
33
|
+
network?: 'mainnet' | 'devnet';
|
|
34
|
+
}
|
|
35
|
+
/** Options for preparing payload only (no POST). Same as MintCredentialNftViaServerOptions minus upload/headers. */
|
|
36
|
+
export interface PrepareCredentialNftPayloadOptions {
|
|
37
|
+
/** Recipient's xidentity (base64). Required. */
|
|
38
|
+
xidentity: string;
|
|
39
|
+
/** Network for mint (mainnet | devnet). Default: mainnet */
|
|
40
|
+
network?: 'mainnet' | 'devnet';
|
|
41
|
+
}
|
|
42
|
+
/** Result of prepareCredentialNftPayload: the exact body to POST to upload-and-mint later. */
|
|
43
|
+
export interface PreparedCredentialNftPayload {
|
|
44
|
+
/** Request body to POST to upload-and-mint API (data, contentType, tags, leafOwner, name, description, network). */
|
|
45
|
+
body: Record<string, unknown>;
|
|
46
|
+
/** Recipient Solana address (leafOwner). */
|
|
47
|
+
recipientSolanaAddress: string;
|
|
48
|
+
}
|
|
49
|
+
/** Built-in endpoints for upload-and-mint API */
|
|
50
|
+
export declare const RWA_UPLOAD_AND_MINT_ENDPOINTS: {
|
|
51
|
+
readonly prod: "https://api.yallet.xyz/api/v1/storage/rwa/upload-and-mint";
|
|
52
|
+
readonly dev: "https://api.yallet.xyz/api/v1/storage/rwa/upload-and-mint";
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Build the same upload-and-mint request body as mintCredentialNftViaServer, without sending.
|
|
56
|
+
* Used to store the encrypted note server-side (e.g. Oracle binding) and send only after attestation.
|
|
57
|
+
*
|
|
58
|
+
* @param recipientSolanaAddress - Recipient's Solana address (leafOwner)
|
|
59
|
+
* @param payload - { user_cred, mnemonic?, index, label }
|
|
60
|
+
* @param options - { xidentity, network? }
|
|
61
|
+
* @returns { body, recipientSolanaAddress } — body is the exact JSON to POST to upload-and-mint later
|
|
62
|
+
*/
|
|
63
|
+
export declare function prepareCredentialNftPayload(recipientSolanaAddress: string, payload: CredentialNftPayload, options: PrepareCredentialNftPayloadOptions): Promise<PreparedCredentialNftPayload>;
|
|
64
|
+
/**
|
|
65
|
+
* Mint credential payload via server (upload-and-mint API).
|
|
66
|
+
*
|
|
67
|
+
* Caller provides xidentity from recipient-addresses. No registry or signer.
|
|
68
|
+
*
|
|
69
|
+
* @param recipientSolanaAddress - Recipient's Solana address (leafOwner)
|
|
70
|
+
* @param payload - { user_cred, mnemonic?, index, label }
|
|
71
|
+
* @param options - { xidentity, uploadAndMintApiUrl?, dev?, headers?, network? }
|
|
72
|
+
* @returns { success, txId?, error? }
|
|
73
|
+
*/
|
|
74
|
+
export declare function mintCredentialNftViaServer(recipientSolanaAddress: string, payload: CredentialNftPayload, options: MintCredentialNftViaServerOptions): Promise<CredentialMintResult>;
|
|
75
|
+
//# sourceMappingURL=credential-nft-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-nft-server.d.ts","sourceRoot":"","sources":["../src/credential-nft-server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,6CAA6C;AAC7C,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,2HAA2H;IAC3H,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,qCAAqC;AACrC,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,mCAAmC;AACnC,MAAM,WAAW,iCAAiC;IAChD,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,8EAA8E;IAC9E,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,4DAA4D;IAC5D,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;CAChC;AAED,oHAAoH;AACpH,MAAM,WAAW,kCAAkC;IACjD,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;CAChC;AAED,8FAA8F;AAC9F,MAAM,WAAW,4BAA4B;IAC3C,oHAAoH;IACpH,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,4CAA4C;IAC5C,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,iDAAiD;AACjD,eAAO,MAAM,6BAA6B;;;CAGhC,CAAC;AAYX;;;;;;;;GAQG;AACH,wBAAsB,2BAA2B,CAC/C,sBAAsB,EAAE,MAAM,EAC9B,OAAO,EAAE,oBAAoB,EAC7B,OAAO,EAAE,kCAAkC,GAC1C,OAAO,CAAC,4BAA4B,CAAC,CAoDvC;AAED;;;;;;;;;GASG;AACH,wBAAsB,0BAA0B,CAC9C,sBAAsB,EAAE,MAAM,EAC9B,OAAO,EAAE,oBAAoB,EAC7B,OAAO,EAAE,iCAAiC,GACzC,OAAO,CAAC,oBAAoB,CAAC,CA6C/B"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yault credential NFT — server-side mint flow.
|
|
3
|
+
*
|
|
4
|
+
* Encrypts credential payload locally with recipient's xidentity, then POSTs
|
|
5
|
+
* to upload-and-mint API. No registry, signer, or client-side mint needed.
|
|
6
|
+
*/
|
|
7
|
+
import { AssetType } from './types.js';
|
|
8
|
+
import { ECIESEncryptor } from './encryption.js';
|
|
9
|
+
import { encryptAsset } from './encryption.js';
|
|
10
|
+
/** Built-in endpoints for upload-and-mint API */
|
|
11
|
+
export const RWA_UPLOAD_AND_MINT_ENDPOINTS = {
|
|
12
|
+
prod: 'https://api.yallet.xyz/api/v1/storage/rwa/upload-and-mint',
|
|
13
|
+
dev: 'https://api.yallet.xyz/api/v1/storage/rwa/upload-and-mint',
|
|
14
|
+
};
|
|
15
|
+
const NOTE_TITLE = 'Yault Release Credentials';
|
|
16
|
+
function bytesToBase64(bytes) {
|
|
17
|
+
let binary = '';
|
|
18
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
19
|
+
binary += String.fromCharCode(bytes[i]);
|
|
20
|
+
}
|
|
21
|
+
return btoa(binary);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build the same upload-and-mint request body as mintCredentialNftViaServer, without sending.
|
|
25
|
+
* Used to store the encrypted note server-side (e.g. Oracle binding) and send only after attestation.
|
|
26
|
+
*
|
|
27
|
+
* @param recipientSolanaAddress - Recipient's Solana address (leafOwner)
|
|
28
|
+
* @param payload - { user_cred, mnemonic?, index, label }
|
|
29
|
+
* @param options - { xidentity, network? }
|
|
30
|
+
* @returns { body, recipientSolanaAddress } — body is the exact JSON to POST to upload-and-mint later
|
|
31
|
+
*/
|
|
32
|
+
export async function prepareCredentialNftPayload(recipientSolanaAddress, payload, options) {
|
|
33
|
+
const { xidentity, network = 'mainnet' } = options;
|
|
34
|
+
if (!xidentity || !xidentity.trim()) {
|
|
35
|
+
throw new Error('xidentity is required');
|
|
36
|
+
}
|
|
37
|
+
const note = {
|
|
38
|
+
title: NOTE_TITLE,
|
|
39
|
+
content: JSON.stringify(payload),
|
|
40
|
+
metadata: { createdAt: new Date().toISOString() },
|
|
41
|
+
};
|
|
42
|
+
const name = `${NOTE_TITLE} — ${payload.label}`;
|
|
43
|
+
const description = `Path index ${payload.index}. Decrypt in Yallet to view credentials.`;
|
|
44
|
+
const encryptor = new ECIESEncryptor();
|
|
45
|
+
const encrypted = await encryptAsset(note, AssetType.NOTE, xidentity.trim(), encryptor);
|
|
46
|
+
const payloadForStorage = {
|
|
47
|
+
encrypted: {
|
|
48
|
+
ephemeral_pub: encrypted.ephemeral_pub,
|
|
49
|
+
encrypted_aes_key: encrypted.encrypted_aes_key,
|
|
50
|
+
iv: encrypted.iv,
|
|
51
|
+
encrypted_data: encrypted.encrypted_data,
|
|
52
|
+
},
|
|
53
|
+
metadata: {
|
|
54
|
+
assetType: AssetType.NOTE,
|
|
55
|
+
direction: 'received',
|
|
56
|
+
network,
|
|
57
|
+
version: encrypted.version,
|
|
58
|
+
uuid: encrypted.uuid,
|
|
59
|
+
timestamp: encrypted.timestamp,
|
|
60
|
+
dataSize: encrypted.dataSize,
|
|
61
|
+
uploadedAt: Date.now(),
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
const jsonString = JSON.stringify(payloadForStorage);
|
|
65
|
+
const dataBase64 = bytesToBase64(new TextEncoder().encode(jsonString));
|
|
66
|
+
const body = {
|
|
67
|
+
data: dataBase64,
|
|
68
|
+
contentType: 'application/json',
|
|
69
|
+
tags: { 'Yallet-Type': 'encrypted-asset', 'Asset-Type': AssetType.NOTE, 'Direction': 'received' },
|
|
70
|
+
leafOwner: recipientSolanaAddress,
|
|
71
|
+
name,
|
|
72
|
+
description,
|
|
73
|
+
network,
|
|
74
|
+
};
|
|
75
|
+
return { body, recipientSolanaAddress };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Mint credential payload via server (upload-and-mint API).
|
|
79
|
+
*
|
|
80
|
+
* Caller provides xidentity from recipient-addresses. No registry or signer.
|
|
81
|
+
*
|
|
82
|
+
* @param recipientSolanaAddress - Recipient's Solana address (leafOwner)
|
|
83
|
+
* @param payload - { user_cred, mnemonic?, index, label }
|
|
84
|
+
* @param options - { xidentity, uploadAndMintApiUrl?, dev?, headers?, network? }
|
|
85
|
+
* @returns { success, txId?, error? }
|
|
86
|
+
*/
|
|
87
|
+
export async function mintCredentialNftViaServer(recipientSolanaAddress, payload, options) {
|
|
88
|
+
const { xidentity, uploadAndMintApiUrl, dev = false, headers = {}, network = 'mainnet' } = options;
|
|
89
|
+
if (!xidentity || !xidentity.trim()) {
|
|
90
|
+
return { success: false, error: 'xidentity is required' };
|
|
91
|
+
}
|
|
92
|
+
const apiUrl = uploadAndMintApiUrl ||
|
|
93
|
+
(dev ? RWA_UPLOAD_AND_MINT_ENDPOINTS.dev : RWA_UPLOAD_AND_MINT_ENDPOINTS.prod);
|
|
94
|
+
const { body } = await prepareCredentialNftPayload(recipientSolanaAddress, payload, { xidentity, network });
|
|
95
|
+
try {
|
|
96
|
+
const response = await fetch(apiUrl, {
|
|
97
|
+
method: 'POST',
|
|
98
|
+
headers: {
|
|
99
|
+
'Content-Type': 'application/json',
|
|
100
|
+
...headers,
|
|
101
|
+
},
|
|
102
|
+
body: JSON.stringify(body),
|
|
103
|
+
});
|
|
104
|
+
const result = (await response.json().catch(() => ({})));
|
|
105
|
+
if (!response.ok) {
|
|
106
|
+
return {
|
|
107
|
+
success: false,
|
|
108
|
+
error: result?.error || response.statusText || 'Upload-and-mint failed',
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const signature = result?.mint?.signature;
|
|
112
|
+
return {
|
|
113
|
+
success: true,
|
|
114
|
+
txId: signature,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
119
|
+
return { success: false, error: message };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=credential-nft-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-nft-server.js","sourceRoot":"","sources":["../src/credential-nft-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yault credential NFT — mint release credentials (user_cred + optional mnemonic)
|
|
3
|
+
* as an encrypted message cNFT to the recipient.
|
|
4
|
+
*
|
|
5
|
+
* Used by Yault webapp after Plan submit: custody WASM generates credentials,
|
|
6
|
+
* this function mints them to the recipient's Solana address via RWA SDK mintMessage.
|
|
7
|
+
*/
|
|
8
|
+
import type { YalletRWASDK } from './sdk.js';
|
|
9
|
+
/** Payload shape agreed with Yault webapp (mnemonic optional until path design includes it). */
|
|
10
|
+
export interface CredentialNftPayload {
|
|
11
|
+
user_cred: string;
|
|
12
|
+
mnemonic?: string | null;
|
|
13
|
+
index: number;
|
|
14
|
+
label: string;
|
|
15
|
+
}
|
|
16
|
+
/** Result shape expected by Yault: success, txId (assetId or signature), error. */
|
|
17
|
+
export interface CredentialMintResult {
|
|
18
|
+
success: boolean;
|
|
19
|
+
txId?: string;
|
|
20
|
+
error?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Mint credential payload as an encrypted note cNFT to the recipient.
|
|
24
|
+
*
|
|
25
|
+
* @param sdk - Initialized YalletRWASDK (config, signer, registry set)
|
|
26
|
+
* @param recipientSolanaAddress - Recipient's Solana address (must be registered in SDK registry with xidentity)
|
|
27
|
+
* @param payload - { user_cred, mnemonic?, index, label }
|
|
28
|
+
* @returns { success, txId?, error? } for Yault UI
|
|
29
|
+
*/
|
|
30
|
+
export declare function mintCredentialNft(sdk: YalletRWASDK, recipientSolanaAddress: string, payload: CredentialNftPayload): Promise<CredentialMintResult>;
|
|
31
|
+
//# sourceMappingURL=credential-nft.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-nft.d.ts","sourceRoot":"","sources":["../src/credential-nft.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C,gGAAgG;AAChG,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,mFAAmF;AACnF,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,YAAY,EACjB,sBAAsB,EAAE,MAAM,EAC9B,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CAuB/B"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yault credential NFT — mint release credentials (user_cred + optional mnemonic)
|
|
3
|
+
* as an encrypted message cNFT to the recipient.
|
|
4
|
+
*
|
|
5
|
+
* Used by Yault webapp after Plan submit: custody WASM generates credentials,
|
|
6
|
+
* this function mints them to the recipient's Solana address via RWA SDK mintMessage.
|
|
7
|
+
*/
|
|
8
|
+
const NOTE_TITLE = 'Yault Release Credentials';
|
|
9
|
+
/**
|
|
10
|
+
* Mint credential payload as an encrypted note cNFT to the recipient.
|
|
11
|
+
*
|
|
12
|
+
* @param sdk - Initialized YalletRWASDK (config, signer, registry set)
|
|
13
|
+
* @param recipientSolanaAddress - Recipient's Solana address (must be registered in SDK registry with xidentity)
|
|
14
|
+
* @param payload - { user_cred, mnemonic?, index, label }
|
|
15
|
+
* @returns { success, txId?, error? } for Yault UI
|
|
16
|
+
*/
|
|
17
|
+
export async function mintCredentialNft(sdk, recipientSolanaAddress, payload) {
|
|
18
|
+
const note = {
|
|
19
|
+
title: NOTE_TITLE,
|
|
20
|
+
content: JSON.stringify(payload),
|
|
21
|
+
metadata: { createdAt: new Date().toISOString() },
|
|
22
|
+
};
|
|
23
|
+
const result = await sdk.mintMessage(note, recipientSolanaAddress, {
|
|
24
|
+
name: `${NOTE_TITLE} — ${payload.label}`,
|
|
25
|
+
description: `Path index ${payload.index}. Decrypt in Yallet to view credentials.`,
|
|
26
|
+
});
|
|
27
|
+
if (result.success) {
|
|
28
|
+
return {
|
|
29
|
+
success: true,
|
|
30
|
+
txId: result.assetId ?? result.signature ?? undefined,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
success: false,
|
|
35
|
+
error: result.error ?? 'Mint failed',
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=credential-nft.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-nft.js","sourceRoot":"","sources":["../src/credential-nft.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAoBH,MAAM,UAAU,GAAG,2BAA2B,CAAC;AAE/C;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAiB,EACjB,sBAA8B,EAC9B,OAA6B;IAE7B,MAAM,IAAI,GAAG;QACX,KAAK,EAAE,UAAU;QACjB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;QAChC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE;KAClD,CAAC;IAEF,MAAM,MAAM,GAAe,MAAM,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,sBAAsB,EAAE;QAC7E,IAAI,EAAE,GAAG,UAAU,MAAM,OAAO,CAAC,KAAK,EAAE;QACxC,WAAW,EAAE,cAAc,OAAO,CAAC,KAAK,0CAA0C;KACnF,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,SAAS,IAAI,SAAS;SACtD,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,aAAa;KACrC,CAAC;AACJ,CAAC"}
|