@medialane/sdk 0.1.0 → 0.2.1

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 CHANGED
@@ -1,48 +1,59 @@
1
- <img width="1260" height="640" alt="image" src="https://github.com/user-attachments/assets/a72bca86-bb82-42c4-8f61-9558484df5b9" />
1
+ <img width="1260" height="640" alt="Medialane SDK" src="https://github.com/user-attachments/assets/a72bca86-bb82-42c4-8f61-9558484df5b9" />
2
2
 
3
- # Medialane SDK
3
+ # @medialane/sdk
4
4
 
5
- The Medialane SDK provides a unified interface for interacting with the Medialane marketplace, offering both **on-chain operations** (create listings, make offers, fulfill orders) and **REST API access** (search tokens, manage orders, upload metadata).
5
+ **Framework-agnostic TypeScript SDK for the Medialane IP marketplace on Starknet**
6
6
 
7
- Framework-agnostic TypeScript SDK for [Medialane.xyz](https://medialane.xyz) portal for tokenization and monetization services and [Medialane.io](https://medialane.io) NFT marketplace.
7
+ The Medialane SDK provides a unified interface for interacting with the Medialane marketplace — both **on-chain operations** (create listings, make offers, fulfill orders, mint IP assets) and **REST API access** (search tokens, manage orders, upload metadata to IPFS). Built for [Medialane.io](https://medialane.io) and [Medialane.xyz](https://medialane.xyz).
8
+
9
+ ---
8
10
 
9
11
  ## Features
10
12
 
11
- **On-Chain Operations**
13
+ **On-Chain Operations**
12
14
  - Create listings (ERC-721 for sale)
13
15
  - Make offers (bid with ERC-20)
14
16
  - Fulfill orders (purchase NFTs)
15
17
  - Cancel active orders
16
- - Atomic multi-item checkout
18
+ - Atomic multi-item cart checkout
17
19
  - Built-in approval checking
18
20
  - SNIP-12 typed data signing
19
-
20
- 🌐 **REST API**
21
- - Query orders, tokens, and collections
22
- - Search across the marketplace
23
- - Stream activities and transactions
24
- - Manage API keys and webhooks (authenticated)
25
- - Upload metadata to IPFS
26
-
27
- 🔧 **Developer-Friendly**
21
+ - Mint IP NFTs into any collection
22
+ - Deploy new ERC-721 collections
23
+
24
+ **REST API Client**
25
+ - Query orders, tokens, collections, and activities
26
+ - Full-text search across the marketplace
27
+ - Intent-based transaction orchestration
28
+ - Upload metadata and files to IPFS (Pinata)
29
+ - Tenant portal: API keys, webhooks, usage
30
+
31
+ **IP Metadata Types**
32
+ - `IpAttribute` — typed OpenSea ERC-721 attribute
33
+ - `IpNftMetadata` — full IPFS metadata shape with licensing fields
34
+ - `ApiTokenMetadata` — indexed token metadata with all licensing attributes
35
+ - Berne Convention-compatible licensing data model
36
+
37
+ **Developer-Friendly**
28
38
  - Framework-agnostic TypeScript
29
- - Dual ESM/CJS builds
30
- - Zod schema validation
39
+ - Dual ESM + CJS builds
40
+ - Zod schema config validation
31
41
  - Full type safety
32
- - Zero runtime dependencies (except Zod)
33
42
  - Peer dependency: `starknet >= 6.0.0`
34
43
 
44
+ ---
45
+
35
46
  ## Installation
36
47
 
37
48
  ```bash
38
49
  npm install @medialane/sdk starknet
39
50
  # or
40
- yarn add @medialane/sdk starknet
41
- # or
42
51
  bun add @medialane/sdk starknet
52
+ # or
53
+ yarn add @medialane/sdk starknet
43
54
  ```
44
55
 
45
- The SDK requires `starknet >= 6.0.0` as a peer dependency for on-chain operations.
56
+ ---
46
57
 
47
58
  ## Quick Start
48
59
 
@@ -53,63 +64,43 @@ import { MedialaneClient } from "@medialane/sdk";
53
64
 
54
65
  const client = new MedialaneClient({
55
66
  network: "mainnet", // "mainnet" | "sepolia"
56
- rpcUrl: "https://starknet-mainnet.public.blastapi.io", // optional; auto-configured if omitted
57
- backendUrl: "https://api.medialane.xyz", // optional; required for .api methods
58
- apiKey: "ml_live_...", // optional; enables authenticated API routes
67
+ rpcUrl: "https://starknet-mainnet.public.blastapi.io", // optional; defaults to BlastAPI
68
+ backendUrl: "https://api.medialane.xyz", // required for .api methods
69
+ apiKey: "ml_live_...", // from Medialane Portal
59
70
  });
60
71
  ```
61
72
 
62
- ### Query the Marketplace (REST API)
63
-
64
- ```typescript
65
- // Get active listings
66
- const orders = await client.api.getOrders({
67
- status: "active",
68
- sort: "newest",
69
- page: 1,
70
- limit: 20,
71
- });
73
+ ---
72
74
 
73
- // Search for a specific token
74
- const search = await client.api.search("vintage-nft", 10);
75
+ ## Marketplace Operations (On-Chain)
75
76
 
76
- // Get activities
77
- const activities = await client.api.getActivities({
78
- type: "sale",
79
- page: 1
80
- });
81
- ```
77
+ All methods require a `starknet.js` `AccountInterface`. Nonce management, SNIP-12 signing, and `waitForTransaction` are handled automatically.
82
78
 
83
- ### Create a Listing (On-Chain)
79
+ ### Create a Listing
84
80
 
85
81
  ```typescript
86
82
  import { Account } from "starknet";
87
83
 
88
- const account: Account = /* your starknet.js Account */;
89
-
90
84
  const result = await client.marketplace.createListing(account, {
91
- nftContract: "0x05e73b7be06d82beeb390a0e0d655f2c9e7cf519658e04f05d9c690ccc41da03",
85
+ nftContract: "0x05e73b7...",
92
86
  tokenId: 42n,
93
- currency: "USDC", // one of: "USDC", "USDT", "ETH", "STRK"
87
+ currency: "USDC",
94
88
  price: "1000000", // 1 USDC (6 decimals)
95
- endTime: Math.floor(Date.now() / 1000) + 86400 * 30, // 30 days from now
89
+ endTime: Math.floor(Date.now() / 1000) + 86400 * 30, // 30 days
96
90
  });
97
-
98
- console.log("Listing created:", result.txHash);
91
+ console.log("Listed:", result.txHash);
99
92
  ```
100
93
 
101
94
  ### Make an Offer
102
95
 
103
96
  ```typescript
104
97
  const result = await client.marketplace.makeOffer(account, {
105
- nftContract: "0x05e73b7be06d82beeb390a0e0d655f2c9e7cf519658e04f05d9c690ccc41da03",
98
+ nftContract: "0x05e73b7...",
106
99
  tokenId: 42n,
107
100
  currency: "USDC",
108
101
  price: "500000", // 0.5 USDC
109
- endTime: Math.floor(Date.now() / 1000) + 86400 * 7, // 7 days
102
+ endTime: Math.floor(Date.now() / 1000) + 86400 * 7,
110
103
  });
111
-
112
- console.log("Offer created:", result.txHash);
113
104
  ```
114
105
 
115
106
  ### Fulfill an Order
@@ -117,227 +108,271 @@ console.log("Offer created:", result.txHash);
117
108
  ```typescript
118
109
  const result = await client.marketplace.fulfillOrder(account, {
119
110
  orderHash: "0x...",
120
- fulfiller: "0x...", // your address
111
+ fulfiller: account.address,
121
112
  });
122
-
123
- console.log("Order fulfilled:", result.txHash);
124
113
  ```
125
114
 
126
- ### Checkout Multiple Items
115
+ ### Cart Checkout (Multiple Items)
127
116
 
128
117
  ```typescript
129
118
  const result = await client.marketplace.checkoutCart(account, [
130
- {
131
- orderHash: "0x...",
132
- fulfiller: "0x...",
133
- },
134
- {
135
- orderHash: "0x...",
136
- fulfiller: "0x...",
137
- },
119
+ { orderHash: "0x...", fulfiller: account.address },
120
+ { orderHash: "0x...", fulfiller: account.address },
138
121
  ]);
139
-
140
- console.log("Cart checked out:", result.txHash);
141
122
  ```
142
123
 
143
- ## Configuration
144
-
145
- The `MedialaneClient` constructor accepts a `MedialaneConfig` object with the following options:
146
-
147
- | Option | Type | Default | Description |
148
- |--------|------|---------|-------------|
149
- | `network` | `"mainnet" \| "sepolia"` | `"mainnet"` | Starknet network |
150
- | `rpcUrl` | `string` | BlastAPI endpoint | JSON-RPC URL for the network |
151
- | `backendUrl` | `string` | *(required for `.api` calls)* | Medialane backend API base URL |
152
- | `apiKey` | `string` | - | API key for authenticated routes (obtained from Medialane Portal) |
153
- | `marketplaceContract` | `string` | Network-specific default | Marketplace contract address |
124
+ ### Cancel an Order
154
125
 
155
- **Note:** If `backendUrl` is not provided, calling any `.api.*` method will throw an error with instructions to configure it.
126
+ ```typescript
127
+ const result = await client.marketplace.cancelOrder(account, {
128
+ orderHash: "0x...",
129
+ offerer: account.address,
130
+ });
131
+ ```
156
132
 
157
- ## API Reference
133
+ ### Mint an IP Asset
158
134
 
159
- ### Marketplace Module
135
+ ```typescript
136
+ const result = await client.marketplace.mint(account, {
137
+ collectionId: "1", // collection ID on the registry
138
+ recipient: account.address,
139
+ tokenUri: "ipfs://...", // IPFS URI of the metadata JSON
140
+ });
141
+ ```
160
142
 
161
- All methods require a `starknet.js` `AccountInterface`. They handle nonce management, SNIP-12 signing, and transaction waiting automatically.
143
+ ### Deploy a Collection
162
144
 
163
- #### Write Operations
145
+ ```typescript
146
+ const result = await client.marketplace.createCollection(account, {
147
+ name: "My Creative Works",
148
+ symbol: "MCW",
149
+ baseUri: "",
150
+ });
151
+ ```
164
152
 
165
- | Method | Description |
166
- |--------|-------------|
167
- | `createListing(account, params)` | List an ERC-721 for sale. Auto-checks approval; includes approve call if needed. |
168
- | `makeOffer(account, params)` | Bid on an ERC-721 with ERC-20. Includes token approval + order registration. |
169
- | `fulfillOrder(account, params)` | Purchase a listed NFT. Fetches nonce and signs fulfillment typed data. |
170
- | `cancelOrder(account, params)` | Cancel an active order. Fetches nonce and signs cancellation typed data. |
171
- | `checkoutCart(account, items)` | Atomic multicall for multiple purchases. One approve per unique token, sequential nonces. |
153
+ ---
172
154
 
173
- #### View Operations
155
+ ## REST API
174
156
 
175
- | Method | Description |
176
- |--------|-------------|
177
- | `getOrderDetails(orderHash)` | Fetch order details from the contract. |
178
- | `getNonce(address)` | Get the current nonce for an address. |
157
+ ### Query Orders
179
158
 
180
- ### REST API Client
159
+ ```typescript
160
+ const orders = await client.api.getOrders({
161
+ status: "ACTIVE",
162
+ sort: "price_asc",
163
+ currency: "0x033068...", // USDC address
164
+ page: 1,
165
+ limit: 20,
166
+ });
181
167
 
182
- The `client.api` object provides access to all backend endpoints. All methods throw `MedialaneApiError` on non-2xx responses.
168
+ const order = await client.api.getOrder("0x...");
169
+ const tokenOrders = await client.api.getActiveOrdersForToken(contract, tokenId);
170
+ const userOrders = await client.api.getOrdersByUser(address);
171
+ ```
183
172
 
184
- #### Orders
173
+ ### Query Tokens
185
174
 
186
175
  ```typescript
187
- client.api.getOrders(query?) // List all orders with optional filters
188
- client.api.getOrder(orderHash) // Get a specific order
189
- client.api.getActiveOrdersForToken(...) // Get active orders for a token
190
- client.api.getOrdersByUser(address, ...) // Get orders by user
176
+ const token = await client.api.getToken(contract, tokenId);
177
+ const tokens = await client.api.getTokensByOwner(address);
178
+ const history = await client.api.getTokenHistory(contract, tokenId);
191
179
  ```
192
180
 
193
- #### Tokens
181
+ ### Query Collections
194
182
 
195
183
  ```typescript
196
- client.api.getToken(contract, tokenId, wait?) // Get token metadata
197
- client.api.getTokensByOwner(address, ...) // Get tokens owned by address
198
- client.api.getTokenHistory(contract, tokenId) // Get token transaction history
184
+ const collections = await client.api.getCollections();
185
+ const collection = await client.api.getCollection(contract);
186
+ const tokens = await client.api.getCollectionTokens(contract);
199
187
  ```
200
188
 
201
- #### Collections
189
+ ### Search
202
190
 
203
191
  ```typescript
204
- client.api.getCollections(page?, limit?) // List all collections
205
- client.api.getCollection(contract) // Get collection details
206
- client.api.getCollectionTokens(contract, ...) // Get tokens in collection
192
+ const results = await client.api.search("landscape painting", 10);
193
+ // results.data.tokens matching tokens
194
+ // results.data.collections matching collections
207
195
  ```
208
196
 
209
- #### Activities
197
+ ### Activities
210
198
 
211
199
  ```typescript
212
- client.api.getActivities(query?) // Get marketplace activities
213
- client.api.getActivitiesByAddress(address) // Get activities by user
200
+ const feed = await client.api.getActivities({ type: "sale", page: 1 });
201
+ const userFeed = await client.api.getActivitiesByAddress(address);
214
202
  ```
215
203
 
216
- #### Search
204
+ ### Upload Metadata to IPFS
217
205
 
218
206
  ```typescript
219
- client.api.search(query, limit?) // Search tokens and collections
207
+ // Upload a file
208
+ const fileResult = await client.api.uploadFile(imageFile);
209
+ // fileResult.data.url → "ipfs://..."
210
+
211
+ // Upload metadata JSON
212
+ const metaResult = await client.api.uploadMetadata({
213
+ name: "My Work",
214
+ description: "...",
215
+ image: "ipfs://...",
216
+ external_url: "https://medialane.io",
217
+ attributes: [
218
+ { trait_type: "License", value: "CC BY-NC" },
219
+ { trait_type: "Commercial Use", value: "No" },
220
+ // ...
221
+ ],
222
+ });
223
+ // metaResult.data.url → "ipfs://..."
220
224
  ```
221
225
 
222
- #### Intents (Advanced)
226
+ ### Intents (Advanced)
227
+
228
+ The intent system handles the SNIP-12 signing flow for marketplace operations:
223
229
 
224
230
  ```typescript
225
- client.api.createListingIntent(params) // Create listing intent
226
- client.api.createOfferIntent(params) // Create offer intent
227
- client.api.createFulfillIntent(params) // Create fulfill intent
228
- client.api.createCancelIntent(params) // Create cancel intent
229
- client.api.submitIntentSignature(id, sig) // Submit signature for intent
230
- ```
231
+ // 1. Create intent (gets typedData to sign)
232
+ const intent = await client.api.createListingIntent({
233
+ offerer: address,
234
+ nftContract: "0x...",
235
+ tokenId: "42",
236
+ currency: "0x033068...",
237
+ price: "1000000",
238
+ endTime: Math.floor(Date.now() / 1000) + 86400 * 30,
239
+ });
231
240
 
232
- #### Metadata (IPFS)
241
+ // 2. Sign typedData
242
+ const signature = await account.signMessage(intent.data.typedData);
233
243
 
234
- ```typescript
235
- client.api.uploadMetadata(metadata) // Upload JSON to IPFS
236
- client.api.uploadFile(file) // Upload file to IPFS
237
- client.api.resolveMetadata(uri) // Resolve ipfs://, data:, https://
238
- client.api.getMetadataSignedUrl() // Get presigned Pinata URL
244
+ // 3. Submit signature
245
+ await client.api.submitIntentSignature(intent.data.id, toSignatureArray(signature));
239
246
  ```
240
247
 
241
- #### Portal (Self-Service)
248
+ Mint and collection intents are pre-signed — no signature step needed:
242
249
 
243
250
  ```typescript
244
- client.api.getMe() // Get current user info
245
- client.api.getApiKeys() // List API keys
246
- client.api.createApiKey(label?) // Create new API key
247
- client.api.deleteApiKey(id) // Revoke API key
248
- client.api.getUsage() // Get 30-day request usage
251
+ const mintIntent = await client.api.createMintIntent({
252
+ owner: ownerAddress,
253
+ collectionId: "1",
254
+ recipient: recipientAddress,
255
+ tokenUri: "ipfs://...",
256
+ });
257
+ // mintIntent.data.calls → ready to execute
249
258
  ```
250
259
 
251
- ## Error Handling
260
+ ---
252
261
 
253
- The SDK throws two main error types:
262
+ ## IP Metadata Types
254
263
 
255
264
  ```typescript
256
- import { MedialaneError, MedialaneApiError } from "@medialane/sdk";
257
-
258
- // On-chain errors
259
- try {
260
- await client.marketplace.createListing(account, params);
261
- } catch (error) {
262
- if (error instanceof MedialaneError) {
263
- console.error("On-chain error:", error.message);
264
- }
265
- }
266
-
267
- // REST API errors
268
- try {
269
- await client.api.getOrders();
270
- } catch (error) {
271
- if (error instanceof MedialaneApiError) {
272
- console.error(`API error ${error.status}:`, error.message);
273
- }
274
- }
265
+ import type { IpAttribute, IpNftMetadata, ApiTokenMetadata } from "@medialane/sdk";
266
+
267
+ // Single OpenSea ERC-721 attribute
268
+ const attr: IpAttribute = { trait_type: "License", value: "CC BY-NC-SA" };
269
+
270
+ // Full IPFS metadata shape for a Medialane IP NFT
271
+ const metadata: IpNftMetadata = {
272
+ name: "My Track",
273
+ description: "Original music",
274
+ image: "ipfs://...",
275
+ external_url: "https://medialane.io",
276
+ attributes: [
277
+ { trait_type: "IP Type", value: "Music" },
278
+ { trait_type: "License", value: "CC BY-NC-SA" },
279
+ { trait_type: "Commercial Use", value: "No" },
280
+ { trait_type: "Derivatives", value: "Share-Alike" },
281
+ { trait_type: "Attribution", value: "Required" },
282
+ { trait_type: "Territory", value: "Worldwide" },
283
+ { trait_type: "AI Policy", value: "Not Allowed" },
284
+ { trait_type: "Royalty", value: "10%" },
285
+ { trait_type: "Standard", value: "Berne Convention" },
286
+ { trait_type: "Registration", value: "2026-03-06" },
287
+ ],
288
+ };
289
+
290
+ // Token from the API — includes indexed licensing fields for fast access
291
+ const token = await client.api.getToken(contract, tokenId);
292
+ token.data.metadata.licenseType; // "CC BY-NC-SA"
293
+ token.data.metadata.commercialUse; // "No"
294
+ token.data.metadata.derivatives; // "Share-Alike"
295
+ token.data.metadata.attributes; // IpAttribute[] | null
275
296
  ```
276
297
 
277
- ## Supported Tokens
278
-
279
- The following tokens are supported for on-chain operations:
298
+ ---
280
299
 
281
- | Symbol | Address | Decimals |
282
- |--------|---------|----------|
283
- | USDC | `0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8` | 6 |
284
- | USDT | `0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8` | 6 |
285
- | ETH | `0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7` | 18 |
286
- | STRK | `0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d` | 18 |
300
+ ## Supported Tokens
287
301
 
288
- Use the token symbol (e.g., `"USDC"`) in SDK methods, or access token details via:
302
+ | Symbol | Type | Address | Decimals |
303
+ |---|---|---|---|
304
+ | USDC | Circle-native (canonical) | `0x033068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb` | 6 |
305
+ | USDC.e | Bridged (Starkgate) | `0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8` | 6 |
306
+ | USDT | Tether | `0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8` | 6 |
307
+ | ETH | Ether | `0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7` | 18 |
308
+ | STRK | Starknet native | `0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d` | 18 |
289
309
 
290
310
  ```typescript
291
- import { getTokenBySymbol, getTokenByAddress } from "@medialane/sdk";
311
+ import { getTokenBySymbol, getTokenByAddress, SUPPORTED_TOKENS } from "@medialane/sdk";
292
312
 
293
313
  const usdc = getTokenBySymbol("USDC");
294
- const token = getTokenByAddress("0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8");
295
-
296
- console.log(usdc.decimals, token.address);
314
+ const token = getTokenByAddress("0x033068...");
297
315
  ```
298
316
 
299
- ## Utilities
317
+ ---
300
318
 
301
- Helper functions for common tasks:
319
+ ## Utilities
302
320
 
303
321
  ```typescript
304
322
  import {
305
- normalizeAddress, // Normalize address to 0x-prefixed lowercase
306
- shortenAddress, // Shorten to 0x1234...5678 format
307
- parseAmount, // Convert human-readable amount to smallest unit (BigInt)
308
- formatAmount, // Convert smallest unit (BigInt) to human-readable string
309
- stringifyBigInts, // Recursively convert BigInts to strings for JSON serialization
323
+ normalizeAddress, // Pad to 64-char 0x-prefixed lowercase hex
324
+ shortenAddress, // "0x1234...5678"
325
+ parseAmount, // Human-readable smallest unit BigInt ("1.5", 6) → 1500000n
326
+ formatAmount, // Smallest unit human-readable ("1500000", 6) → "1.5"
327
+ stringifyBigInts, // Recursively convert BigInt string (for JSON)
328
+ u256ToBigInt, // u256 { low, high } → BigInt
310
329
  } from "@medialane/sdk";
311
-
312
- // Address utilities
313
- const addr = normalizeAddress("0x123ABC");
314
- const short = shortenAddress("0x123abc456def789012345678901234567890");
315
-
316
- // Token amounts
317
- const amountWei = parseAmount("1.5", 6); // "1500000" (USDC)
318
- const readable = formatAmount("1500000", 6); // "1.5"
319
330
  ```
320
331
 
321
- ## Advanced Usage
332
+ ---
322
333
 
323
- ### Custom RPC Provider
334
+ ## Error Handling
324
335
 
325
336
  ```typescript
326
- import { RpcProvider } from "starknet";
337
+ import { MedialaneError, MedialaneApiError } from "@medialane/sdk";
327
338
 
328
- const customProvider = new RpcProvider({
329
- nodeUrl: "https://your-custom-rpc.com",
330
- });
339
+ // On-chain errors (marketplace module)
340
+ try {
341
+ await client.marketplace.createListing(account, params);
342
+ } catch (err) {
343
+ if (err instanceof MedialaneError) {
344
+ console.error("On-chain error:", err.message, err.cause);
345
+ }
346
+ }
331
347
 
332
- const client = new MedialaneClient({
333
- network: "mainnet",
334
- rpcUrl: "https://your-custom-rpc.com",
335
- });
348
+ // REST API errors
349
+ try {
350
+ await client.api.getOrders();
351
+ } catch (err) {
352
+ if (err instanceof MedialaneApiError) {
353
+ console.error(`API ${err.status}:`, err.message);
354
+ }
355
+ }
336
356
  ```
337
357
 
338
- ### Signing Typed Data (for integrations)
358
+ ---
339
359
 
340
- For advanced integrations like ChipiPay, you can access the SNIP-12 typed data builders directly:
360
+ ## Configuration Reference
361
+
362
+ | Option | Type | Default | Description |
363
+ |---|---|---|---|
364
+ | `network` | `"mainnet" \| "sepolia"` | `"mainnet"` | Starknet network |
365
+ | `rpcUrl` | `string` | BlastAPI public endpoint | JSON-RPC URL |
366
+ | `backendUrl` | `string` | — | Medialane API base URL (required for `.api.*`) |
367
+ | `apiKey` | `string` | — | API key from [Medialane Portal](https://medialane.xyz) |
368
+ | `marketplaceContract` | `string` | Mainnet default | Marketplace contract override |
369
+ | `collectionContract` | `string` | Mainnet default | Collection registry override |
370
+
371
+ ---
372
+
373
+ ## Advanced: SNIP-12 Typed Data Builders
374
+
375
+ For integrations that handle signing externally (e.g. ChipiPay, Cartridge Controller):
341
376
 
342
377
  ```typescript
343
378
  import {
@@ -348,33 +383,49 @@ import {
348
383
 
349
384
  const typedData = buildOrderTypedData(orderParams, chainId);
350
385
  const signature = await account.signMessage(typedData);
351
-
352
- // Signature can then be submitted via API intents
353
- await client.api.submitIntentSignature(intentId, signature);
386
+ await client.api.submitIntentSignature(intentId, signatureArray);
354
387
  ```
355
388
 
356
- ## Development
389
+ ---
357
390
 
358
- Build and type-check the SDK:
391
+ ## Development
359
392
 
360
393
  ```bash
361
- bun run build # Compile to dist/ (ESM + CJS)
394
+ bun run build # Compile to dist/ (ESM + CJS dual output)
362
395
  bun run dev # Watch mode
363
- bun run typecheck # Type check only (no emit)
396
+ bun run typecheck # tsc --noEmit
364
397
  ```
365
398
 
366
- The SDK uses:
367
- - **tsup** for dual ESM/CJS bundling
368
- - **TypeScript** for type safety
369
- - **Zod** for runtime config validation
399
+ Built with:
400
+ - **tsup** dual ESM/CJS bundling
401
+ - **TypeScript** full type safety
402
+ - **Zod** runtime config validation
403
+ - Peer dep: `starknet >= 6.0.0`
370
404
 
371
- ## License
405
+ ---
372
406
 
373
- [MIT](LICENSE)
407
+ ## Changelog
408
+
409
+ ### v0.2.0
410
+ - `IpAttribute` and `IpNftMetadata` interfaces for IP metadata
411
+ - `ApiTokenMetadata.attributes` typed as `IpAttribute[] | null` (was `unknown`)
412
+ - `ApiTokenMetadata` extended with `derivatives`, `attribution`, `territory`, `aiPolicy`, `royalty`, `registration`, `standard`
413
+ - Added `USDC.e` (bridged USDC via Starkgate) to `SUPPORTED_TOKENS`
414
+
415
+ ### v0.1.0
416
+ - Initial release — orders, tokens, collections, activities, intents, metadata, portal
374
417
 
375
- ## Support
418
+ ---
376
419
 
377
- - **Services App**: [medialane.xyz](https://medialane.xyz)
378
- - **Documentation**: [medialane.xyz/docs](https://medialane.xyz/docs)
379
- - **Issues**: [GitHub Issues](https://github.com/medialane-io/sdk/issues)
380
- - **Medialane Github**: [GitHub Issues](https://github.com/medialane-io)
420
+ ## Links
421
+
422
+ - **Marketplace**: [medialane.io](https://medialane.io)
423
+ - **Developer Portal**: [medialane.xyz](https://medialane.xyz)
424
+ - **npm**: [npmjs.com/package/@medialane/sdk](https://www.npmjs.com/package/@medialane/sdk)
425
+ - **GitHub**: [github.com/medialane-io](https://github.com/medialane-io)
426
+
427
+ ---
428
+
429
+ ## License
430
+
431
+ [MIT](LICENSE)
package/dist/index.cjs CHANGED
@@ -10,11 +10,17 @@ var MARKETPLACE_CONTRACT_MAINNET = "0x059deafbbafbf7051c315cf75a94b03c5547892bc0
10
10
  var COLLECTION_CONTRACT_MAINNET = "0x05e73b7be06d82beeb390a0e0d655f2c9e7cf519658e04f05d9c690ccc41da03";
11
11
  var SUPPORTED_TOKENS = [
12
12
  {
13
- // Circle-native USDC on Starknet (canonical)
13
+ // Circle-native USDC on Starknet (canonical — preferred)
14
14
  symbol: "USDC",
15
15
  address: "0x033068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb",
16
16
  decimals: 6
17
17
  },
18
+ {
19
+ // Bridged USDC.e (Ethereum USDC bridged via Starkgate)
20
+ symbol: "USDC.e",
21
+ address: "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8",
22
+ decimals: 6
23
+ },
18
24
  {
19
25
  symbol: "USDT",
20
26
  address: "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8",