rwa-tokenized-sdk 0.1.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 +741 -0
- package/dist/client/rwa.d.ts +280 -0
- package/dist/client/rwa.d.ts.map +1 -0
- package/dist/client/rwa.js +708 -0
- package/dist/client/rwa.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +130 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,708 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RWA Launchpad Client
|
|
3
|
+
*
|
|
4
|
+
* Complete SDK for interacting with RWA Factory and Property contracts.
|
|
5
|
+
* Supports all contract operations including:
|
|
6
|
+
*
|
|
7
|
+
* Factory Operations:
|
|
8
|
+
* - launchProperty: Create new RWA properties
|
|
9
|
+
* - getAllProperties: Get all property addresses
|
|
10
|
+
* - getPropertyCount: Get total property count
|
|
11
|
+
* - getProperty: Get property by index
|
|
12
|
+
* - getPropertyInfo: Get property information
|
|
13
|
+
* - getUserProperties: Get user's properties
|
|
14
|
+
* - getUserPropertyCount: Get user's property count
|
|
15
|
+
* - getUserPropertyByIndex: Get user property by index
|
|
16
|
+
* - isValidProperty: Check if address is valid property
|
|
17
|
+
* - getFactoryOwner: Get factory owner
|
|
18
|
+
* - renounceFactoryOwnership: Renounce factory ownership
|
|
19
|
+
* - transferFactoryOwnership: Transfer factory ownership
|
|
20
|
+
*
|
|
21
|
+
* Property ERC1155 Operations:
|
|
22
|
+
* - getPropertyDetails: Get property details from contract
|
|
23
|
+
* - getTokenBalance: Get token balance for user
|
|
24
|
+
* - getBatchTokenBalances: Get batch token balances
|
|
25
|
+
* - transferTokens: Transfer tokens (safeTransferFrom)
|
|
26
|
+
* - batchTransferTokens: Batch transfer tokens
|
|
27
|
+
* - setApprovalForAll: Approve/revoke operator
|
|
28
|
+
* - isApprovedForAll: Check operator approval
|
|
29
|
+
* - supportsInterface: Check interface support (ERC165)
|
|
30
|
+
*
|
|
31
|
+
* Property Ownership Operations:
|
|
32
|
+
* - getPropertyOwner: Get property owner
|
|
33
|
+
* - renouncePropertyOwnership: Renounce property ownership
|
|
34
|
+
* - transferPropertyOwnership: Transfer property ownership
|
|
35
|
+
*
|
|
36
|
+
* Works with any web3 provider (ethers.js v5 or v6).
|
|
37
|
+
*/
|
|
38
|
+
// Factory Contract ABI (complete interface)
|
|
39
|
+
const FACTORY_ABI = [
|
|
40
|
+
{
|
|
41
|
+
inputs: [
|
|
42
|
+
{ name: "_assetName", type: "string" },
|
|
43
|
+
{ name: "_assetType", type: "string" },
|
|
44
|
+
{ name: "_description", type: "string" },
|
|
45
|
+
{ name: "_isOwner", type: "bool" },
|
|
46
|
+
{ name: "_approximatedValue", type: "uint256" },
|
|
47
|
+
{ name: "_totalSupply", type: "uint256" },
|
|
48
|
+
{ name: "_propertyAddress", type: "string" },
|
|
49
|
+
{ name: "_squareMeters", type: "uint256" },
|
|
50
|
+
{ name: "_uri", type: "string" }
|
|
51
|
+
],
|
|
52
|
+
name: "launchProperty",
|
|
53
|
+
outputs: [{ name: "property", type: "address" }],
|
|
54
|
+
stateMutability: "nonpayable",
|
|
55
|
+
type: "function"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
inputs: [],
|
|
59
|
+
name: "getAllProperties",
|
|
60
|
+
outputs: [{ name: "", type: "address[]" }],
|
|
61
|
+
stateMutability: "view",
|
|
62
|
+
type: "function"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
inputs: [],
|
|
66
|
+
name: "getPropertyCount",
|
|
67
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
68
|
+
stateMutability: "view",
|
|
69
|
+
type: "function"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
inputs: [{ name: "_index", type: "uint256" }],
|
|
73
|
+
name: "getProperty",
|
|
74
|
+
outputs: [{ name: "", type: "address" }],
|
|
75
|
+
stateMutability: "view",
|
|
76
|
+
type: "function"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
inputs: [{ name: "_propertyAddress", type: "address" }],
|
|
80
|
+
name: "getPropertyInfo",
|
|
81
|
+
outputs: [
|
|
82
|
+
{ name: "assetName", type: "string" },
|
|
83
|
+
{ name: "assetType", type: "string" },
|
|
84
|
+
{ name: "description", type: "string" },
|
|
85
|
+
{ name: "isOwner", type: "bool" },
|
|
86
|
+
{ name: "approximatedValue", type: "uint256" },
|
|
87
|
+
{ name: "totalSupply", type: "uint256" },
|
|
88
|
+
{ name: "propertyAddress", type: "string" },
|
|
89
|
+
{ name: "squareMeters", type: "uint256" }
|
|
90
|
+
],
|
|
91
|
+
stateMutability: "view",
|
|
92
|
+
type: "function"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
inputs: [{ name: "_user", type: "address" }],
|
|
96
|
+
name: "getUserProperties",
|
|
97
|
+
outputs: [{ name: "", type: "address[]" }],
|
|
98
|
+
stateMutability: "view",
|
|
99
|
+
type: "function"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
inputs: [{ name: "_user", type: "address" }],
|
|
103
|
+
name: "getUserPropertyCount",
|
|
104
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
105
|
+
stateMutability: "view",
|
|
106
|
+
type: "function"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
inputs: [
|
|
110
|
+
{ name: "_user", type: "address" },
|
|
111
|
+
{ name: "_index", type: "uint256" }
|
|
112
|
+
],
|
|
113
|
+
name: "getUserPropertyByIndex",
|
|
114
|
+
outputs: [{ name: "", type: "address" }],
|
|
115
|
+
stateMutability: "view",
|
|
116
|
+
type: "function"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
inputs: [{ name: "_propertyAddress", type: "address" }],
|
|
120
|
+
name: "isValidProperty",
|
|
121
|
+
outputs: [{ name: "", type: "bool" }],
|
|
122
|
+
stateMutability: "view",
|
|
123
|
+
type: "function"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
inputs: [],
|
|
127
|
+
name: "owner",
|
|
128
|
+
outputs: [{ name: "", type: "address" }],
|
|
129
|
+
stateMutability: "view",
|
|
130
|
+
type: "function"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
inputs: [],
|
|
134
|
+
name: "renounceOwnership",
|
|
135
|
+
outputs: [],
|
|
136
|
+
stateMutability: "nonpayable",
|
|
137
|
+
type: "function"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
inputs: [{ name: "newOwner", type: "address" }],
|
|
141
|
+
name: "transferOwnership",
|
|
142
|
+
outputs: [],
|
|
143
|
+
stateMutability: "nonpayable",
|
|
144
|
+
type: "function"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
anonymous: false,
|
|
148
|
+
inputs: [
|
|
149
|
+
{ indexed: true, name: "propertyContract", type: "address" },
|
|
150
|
+
{ indexed: true, name: "issuer", type: "address" },
|
|
151
|
+
{ indexed: false, name: "assetName", type: "string" },
|
|
152
|
+
{ indexed: false, name: "assetType", type: "string" },
|
|
153
|
+
{ indexed: true, name: "propertyId", type: "uint256" }
|
|
154
|
+
],
|
|
155
|
+
name: "PropertyLaunched",
|
|
156
|
+
type: "event"
|
|
157
|
+
}
|
|
158
|
+
];
|
|
159
|
+
// Property Contract ABI (complete ERC1155 interface)
|
|
160
|
+
const PROPERTY_ABI = [
|
|
161
|
+
{
|
|
162
|
+
inputs: [],
|
|
163
|
+
name: "getAllDetails",
|
|
164
|
+
outputs: [
|
|
165
|
+
{ name: "", type: "string" },
|
|
166
|
+
{ name: "", type: "string" },
|
|
167
|
+
{ name: "", type: "string" },
|
|
168
|
+
{ name: "", type: "bool" },
|
|
169
|
+
{ name: "", type: "uint256" },
|
|
170
|
+
{ name: "", type: "uint256" },
|
|
171
|
+
{ name: "", type: "string" },
|
|
172
|
+
{ name: "", type: "uint256" }
|
|
173
|
+
],
|
|
174
|
+
stateMutability: "view",
|
|
175
|
+
type: "function"
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
inputs: [
|
|
179
|
+
{ name: "account", type: "address" },
|
|
180
|
+
{ name: "id", type: "uint256" }
|
|
181
|
+
],
|
|
182
|
+
name: "balanceOf",
|
|
183
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
184
|
+
stateMutability: "view",
|
|
185
|
+
type: "function"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
inputs: [
|
|
189
|
+
{ name: "accounts", type: "address[]" },
|
|
190
|
+
{ name: "ids", type: "uint256[]" }
|
|
191
|
+
],
|
|
192
|
+
name: "balanceOfBatch",
|
|
193
|
+
outputs: [{ name: "", type: "uint256[]" }],
|
|
194
|
+
stateMutability: "view",
|
|
195
|
+
type: "function"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
inputs: [
|
|
199
|
+
{ name: "from", type: "address" },
|
|
200
|
+
{ name: "to", type: "address" },
|
|
201
|
+
{ name: "id", type: "uint256" },
|
|
202
|
+
{ name: "value", type: "uint256" },
|
|
203
|
+
{ name: "data", type: "bytes" }
|
|
204
|
+
],
|
|
205
|
+
name: "safeTransferFrom",
|
|
206
|
+
outputs: [],
|
|
207
|
+
stateMutability: "nonpayable",
|
|
208
|
+
type: "function"
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
inputs: [
|
|
212
|
+
{ name: "from", type: "address" },
|
|
213
|
+
{ name: "to", type: "address" },
|
|
214
|
+
{ name: "ids", type: "uint256[]" },
|
|
215
|
+
{ name: "values", type: "uint256[]" },
|
|
216
|
+
{ name: "data", type: "bytes" }
|
|
217
|
+
],
|
|
218
|
+
name: "safeBatchTransferFrom",
|
|
219
|
+
outputs: [],
|
|
220
|
+
stateMutability: "nonpayable",
|
|
221
|
+
type: "function"
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
inputs: [
|
|
225
|
+
{ name: "account", type: "address" },
|
|
226
|
+
{ name: "operator", type: "address" }
|
|
227
|
+
],
|
|
228
|
+
name: "isApprovedForAll",
|
|
229
|
+
outputs: [{ name: "", type: "bool" }],
|
|
230
|
+
stateMutability: "view",
|
|
231
|
+
type: "function"
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
inputs: [
|
|
235
|
+
{ name: "operator", type: "address" },
|
|
236
|
+
{ name: "approved", type: "bool" }
|
|
237
|
+
],
|
|
238
|
+
name: "setApprovalForAll",
|
|
239
|
+
outputs: [],
|
|
240
|
+
stateMutability: "nonpayable",
|
|
241
|
+
type: "function"
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
inputs: [{ name: "", type: "uint256" }],
|
|
245
|
+
name: "uri",
|
|
246
|
+
outputs: [{ name: "", type: "string" }],
|
|
247
|
+
stateMutability: "view",
|
|
248
|
+
type: "function"
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
inputs: [],
|
|
252
|
+
name: "PROPERTY_TOKEN_ID",
|
|
253
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
254
|
+
stateMutability: "view",
|
|
255
|
+
type: "function"
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
inputs: [],
|
|
259
|
+
name: "owner",
|
|
260
|
+
outputs: [{ name: "", type: "address" }],
|
|
261
|
+
stateMutability: "view",
|
|
262
|
+
type: "function"
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
inputs: [],
|
|
266
|
+
name: "renounceOwnership",
|
|
267
|
+
outputs: [],
|
|
268
|
+
stateMutability: "nonpayable",
|
|
269
|
+
type: "function"
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
inputs: [{ name: "newOwner", type: "address" }],
|
|
273
|
+
name: "transferOwnership",
|
|
274
|
+
outputs: [],
|
|
275
|
+
stateMutability: "nonpayable",
|
|
276
|
+
type: "function"
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
inputs: [{ name: "interfaceId", type: "bytes4" }],
|
|
280
|
+
name: "supportsInterface",
|
|
281
|
+
outputs: [{ name: "", type: "bool" }],
|
|
282
|
+
stateMutability: "view",
|
|
283
|
+
type: "function"
|
|
284
|
+
}
|
|
285
|
+
];
|
|
286
|
+
/**
|
|
287
|
+
* Helper to convert string/bigint to bigint
|
|
288
|
+
*/
|
|
289
|
+
function toBigInt(value) {
|
|
290
|
+
return typeof value === "string" ? BigInt(value) : value;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Parse property info from contract response
|
|
294
|
+
*/
|
|
295
|
+
function parsePropertyInfo(data, contractAddress, uri) {
|
|
296
|
+
const [assetName, assetType, description, isOwner, approximatedValue, totalSupply, propertyAddress, squareMeters] = data;
|
|
297
|
+
return {
|
|
298
|
+
assetName,
|
|
299
|
+
assetType,
|
|
300
|
+
description,
|
|
301
|
+
isOwner,
|
|
302
|
+
approximatedValue: approximatedValue.toString(),
|
|
303
|
+
totalSupply: totalSupply.toString(),
|
|
304
|
+
propertyAddress,
|
|
305
|
+
squareMeters: squareMeters.toString(),
|
|
306
|
+
contractAddress,
|
|
307
|
+
uri
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* RWA Factory Client
|
|
312
|
+
*
|
|
313
|
+
* Usage:
|
|
314
|
+
* ```typescript
|
|
315
|
+
* import { createRWAClient } from '@synq/sdk'
|
|
316
|
+
*
|
|
317
|
+
* const rwa = createRWAClient({
|
|
318
|
+
* factoryAddress: '0x...',
|
|
319
|
+
* chainId: 5001
|
|
320
|
+
* })
|
|
321
|
+
*
|
|
322
|
+
* // Launch a property
|
|
323
|
+
* const result = await rwa.launchProperty(params, signer)
|
|
324
|
+
*
|
|
325
|
+
* // Get all properties
|
|
326
|
+
* const properties = await rwa.getAllProperties(provider)
|
|
327
|
+
* ```
|
|
328
|
+
*/
|
|
329
|
+
export function createRWAClient(config) {
|
|
330
|
+
const { factoryAddress } = config;
|
|
331
|
+
if (!factoryAddress) {
|
|
332
|
+
throw new Error("Factory address is required");
|
|
333
|
+
}
|
|
334
|
+
return {
|
|
335
|
+
/**
|
|
336
|
+
* Launch a new RWA property
|
|
337
|
+
*
|
|
338
|
+
* @param params Property launch parameters
|
|
339
|
+
* @param signerOrProvider Signer (for write) or Provider (for read)
|
|
340
|
+
* @returns Transaction hash and property address
|
|
341
|
+
*/
|
|
342
|
+
async launchProperty(params, signerOrProvider) {
|
|
343
|
+
// Normalize parameters
|
|
344
|
+
const normalizedParams = {
|
|
345
|
+
assetName: params.assetName,
|
|
346
|
+
assetType: params.assetType,
|
|
347
|
+
description: params.description,
|
|
348
|
+
isOwner: params.isOwner,
|
|
349
|
+
approximatedValue: toBigInt(params.approximatedValue),
|
|
350
|
+
totalSupply: toBigInt(params.totalSupply),
|
|
351
|
+
propertyAddress: params.propertyAddress,
|
|
352
|
+
squareMeters: toBigInt(params.squareMeters),
|
|
353
|
+
uri: params.uri
|
|
354
|
+
};
|
|
355
|
+
// Validate parameters
|
|
356
|
+
if (!normalizedParams.assetName || normalizedParams.assetName.trim() === "") {
|
|
357
|
+
throw new Error("Asset name is required");
|
|
358
|
+
}
|
|
359
|
+
if (!normalizedParams.assetType || normalizedParams.assetType.trim() === "") {
|
|
360
|
+
throw new Error("Asset type is required");
|
|
361
|
+
}
|
|
362
|
+
if (!normalizedParams.description || normalizedParams.description.trim() === "") {
|
|
363
|
+
throw new Error("Description is required");
|
|
364
|
+
}
|
|
365
|
+
if (normalizedParams.approximatedValue <= 0n) {
|
|
366
|
+
throw new Error("Approximated value must be positive");
|
|
367
|
+
}
|
|
368
|
+
if (normalizedParams.totalSupply <= 0n) {
|
|
369
|
+
throw new Error("Total supply must be positive");
|
|
370
|
+
}
|
|
371
|
+
if (!normalizedParams.uri || normalizedParams.uri.trim() === "") {
|
|
372
|
+
throw new Error("URI is required");
|
|
373
|
+
}
|
|
374
|
+
// Get contract instance
|
|
375
|
+
let contract;
|
|
376
|
+
if (signerOrProvider.getAddress) {
|
|
377
|
+
// It's a signer
|
|
378
|
+
const { Contract } = await import("ethers");
|
|
379
|
+
contract = new Contract(factoryAddress, FACTORY_ABI, signerOrProvider);
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
// It's a provider
|
|
383
|
+
const { Contract } = await import("ethers");
|
|
384
|
+
contract = new Contract(factoryAddress, FACTORY_ABI, signerOrProvider);
|
|
385
|
+
}
|
|
386
|
+
// Call launchProperty
|
|
387
|
+
const tx = await contract.launchProperty(normalizedParams.assetName, normalizedParams.assetType, normalizedParams.description, normalizedParams.isOwner, normalizedParams.approximatedValue, normalizedParams.totalSupply, normalizedParams.propertyAddress, normalizedParams.squareMeters, normalizedParams.uri);
|
|
388
|
+
// Wait for transaction
|
|
389
|
+
const receipt = await tx.wait();
|
|
390
|
+
// Extract property address from event
|
|
391
|
+
const logs = receipt.logs || [];
|
|
392
|
+
let propertyAddress;
|
|
393
|
+
let propertyId;
|
|
394
|
+
// Parse logs to find PropertyLaunched event
|
|
395
|
+
for (const log of logs) {
|
|
396
|
+
try {
|
|
397
|
+
// Try to parse with contract interface
|
|
398
|
+
const parsed = contract.interface.parseLog(log);
|
|
399
|
+
if (parsed && parsed.name === "PropertyLaunched") {
|
|
400
|
+
propertyAddress = parsed.args.propertyContract;
|
|
401
|
+
propertyId = Number(parsed.args.propertyId);
|
|
402
|
+
break;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
catch {
|
|
406
|
+
// Continue to next log if parsing fails
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
if (!propertyAddress) {
|
|
411
|
+
// Fallback: try to decode from receipt directly
|
|
412
|
+
// Some providers structure events differently
|
|
413
|
+
const receiptAny = receipt;
|
|
414
|
+
if (receiptAny.events && receiptAny.events.PropertyLaunched) {
|
|
415
|
+
const event = receiptAny.events.PropertyLaunched;
|
|
416
|
+
propertyAddress = event.args?.propertyContract || event.returnValues?.propertyContract;
|
|
417
|
+
propertyId = Number(event.args?.propertyId || event.returnValues?.propertyId || 0);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
if (!propertyAddress) {
|
|
421
|
+
throw new Error("PropertyLaunched event not found in transaction receipt. " +
|
|
422
|
+
"Please check the transaction hash manually.");
|
|
423
|
+
}
|
|
424
|
+
return {
|
|
425
|
+
transactionHash: receipt.hash || receipt.transactionHash,
|
|
426
|
+
propertyAddress,
|
|
427
|
+
propertyId: propertyId || 0
|
|
428
|
+
};
|
|
429
|
+
},
|
|
430
|
+
/**
|
|
431
|
+
* Get all property addresses
|
|
432
|
+
*/
|
|
433
|
+
async getAllProperties(provider) {
|
|
434
|
+
const { Contract } = await import("ethers");
|
|
435
|
+
const contract = new Contract(factoryAddress, FACTORY_ABI, provider);
|
|
436
|
+
return await contract.getAllProperties();
|
|
437
|
+
},
|
|
438
|
+
/**
|
|
439
|
+
* Get total number of properties
|
|
440
|
+
*/
|
|
441
|
+
async getPropertyCount(provider) {
|
|
442
|
+
const { Contract } = await import("ethers");
|
|
443
|
+
const contract = new Contract(factoryAddress, FACTORY_ABI, provider);
|
|
444
|
+
return await contract.getPropertyCount();
|
|
445
|
+
},
|
|
446
|
+
/**
|
|
447
|
+
* Get property address by index
|
|
448
|
+
*/
|
|
449
|
+
async getProperty(index, provider) {
|
|
450
|
+
const { Contract } = await import("ethers");
|
|
451
|
+
const contract = new Contract(factoryAddress, FACTORY_ABI, provider);
|
|
452
|
+
return await contract.getProperty(BigInt(index));
|
|
453
|
+
},
|
|
454
|
+
/**
|
|
455
|
+
* Get property information from factory
|
|
456
|
+
*/
|
|
457
|
+
async getPropertyInfo(propertyAddress, provider) {
|
|
458
|
+
const { Contract } = await import("ethers");
|
|
459
|
+
const contract = new Contract(factoryAddress, FACTORY_ABI, provider);
|
|
460
|
+
const data = await contract.getPropertyInfo(propertyAddress);
|
|
461
|
+
return parsePropertyInfo(data, propertyAddress);
|
|
462
|
+
},
|
|
463
|
+
/**
|
|
464
|
+
* Get all properties for a user
|
|
465
|
+
*/
|
|
466
|
+
async getUserProperties(userAddress, provider) {
|
|
467
|
+
const { Contract } = await import("ethers");
|
|
468
|
+
const contract = new Contract(factoryAddress, FACTORY_ABI, provider);
|
|
469
|
+
return await contract.getUserProperties(userAddress);
|
|
470
|
+
},
|
|
471
|
+
/**
|
|
472
|
+
* Get user's property count
|
|
473
|
+
*/
|
|
474
|
+
async getUserPropertyCount(userAddress, provider) {
|
|
475
|
+
const { Contract } = await import("ethers");
|
|
476
|
+
const contract = new Contract(factoryAddress, FACTORY_ABI, provider);
|
|
477
|
+
return await contract.getUserPropertyCount(userAddress);
|
|
478
|
+
},
|
|
479
|
+
/**
|
|
480
|
+
* Check if an address is a valid property
|
|
481
|
+
*/
|
|
482
|
+
async isValidProperty(propertyAddress, provider) {
|
|
483
|
+
const { Contract } = await import("ethers");
|
|
484
|
+
const contract = new Contract(factoryAddress, FACTORY_ABI, provider);
|
|
485
|
+
return await contract.isValidProperty(propertyAddress);
|
|
486
|
+
},
|
|
487
|
+
/**
|
|
488
|
+
* Get property details directly from property contract
|
|
489
|
+
*/
|
|
490
|
+
async getPropertyDetails(propertyAddress, provider) {
|
|
491
|
+
const { Contract } = await import("ethers");
|
|
492
|
+
const propertyContract = new Contract(propertyAddress, PROPERTY_ABI, provider);
|
|
493
|
+
const [details, uri] = await Promise.all([
|
|
494
|
+
propertyContract.getAllDetails(),
|
|
495
|
+
propertyContract.uri(1) // PROPERTY_TOKEN_ID is 1
|
|
496
|
+
]);
|
|
497
|
+
return parsePropertyInfo(details, propertyAddress, uri);
|
|
498
|
+
},
|
|
499
|
+
/**
|
|
500
|
+
* Get token balance for a user
|
|
501
|
+
*/
|
|
502
|
+
async getTokenBalance(propertyAddress, userAddress, provider) {
|
|
503
|
+
const { Contract } = await import("ethers");
|
|
504
|
+
const propertyContract = new Contract(propertyAddress, PROPERTY_ABI, provider);
|
|
505
|
+
const tokenId = await propertyContract.PROPERTY_TOKEN_ID();
|
|
506
|
+
return await propertyContract.balanceOf(userAddress, tokenId);
|
|
507
|
+
},
|
|
508
|
+
/**
|
|
509
|
+
* Get factory address
|
|
510
|
+
*/
|
|
511
|
+
getFactoryAddress() {
|
|
512
|
+
return factoryAddress;
|
|
513
|
+
},
|
|
514
|
+
// ============================================
|
|
515
|
+
// FACTORY OWNERSHIP FUNCTIONS
|
|
516
|
+
// ============================================
|
|
517
|
+
/**
|
|
518
|
+
* Get user property by index
|
|
519
|
+
*/
|
|
520
|
+
async getUserPropertyByIndex(userAddress, index, provider) {
|
|
521
|
+
const { Contract } = await import("ethers");
|
|
522
|
+
const contract = new Contract(factoryAddress, FACTORY_ABI, provider);
|
|
523
|
+
return await contract.getUserPropertyByIndex(userAddress, BigInt(index));
|
|
524
|
+
},
|
|
525
|
+
/**
|
|
526
|
+
* Get factory owner address
|
|
527
|
+
*/
|
|
528
|
+
async getFactoryOwner(provider) {
|
|
529
|
+
const { Contract } = await import("ethers");
|
|
530
|
+
const contract = new Contract(factoryAddress, FACTORY_ABI, provider);
|
|
531
|
+
return await contract.owner();
|
|
532
|
+
},
|
|
533
|
+
/**
|
|
534
|
+
* Renounce factory ownership (only owner)
|
|
535
|
+
*/
|
|
536
|
+
async renounceFactoryOwnership(signer) {
|
|
537
|
+
const { Contract } = await import("ethers");
|
|
538
|
+
const contract = new Contract(factoryAddress, FACTORY_ABI, signer);
|
|
539
|
+
const tx = await contract.renounceOwnership();
|
|
540
|
+
const receipt = await tx.wait();
|
|
541
|
+
return receipt.hash || receipt.transactionHash;
|
|
542
|
+
},
|
|
543
|
+
/**
|
|
544
|
+
* Transfer factory ownership (only owner)
|
|
545
|
+
*/
|
|
546
|
+
async transferFactoryOwnership(newOwner, signer) {
|
|
547
|
+
if (!newOwner || newOwner === "0x0000000000000000000000000000000000000000") {
|
|
548
|
+
throw new Error("Invalid new owner address");
|
|
549
|
+
}
|
|
550
|
+
const { Contract } = await import("ethers");
|
|
551
|
+
const contract = new Contract(factoryAddress, FACTORY_ABI, signer);
|
|
552
|
+
const tx = await contract.transferOwnership(newOwner);
|
|
553
|
+
const receipt = await tx.wait();
|
|
554
|
+
return receipt.hash || receipt.transactionHash;
|
|
555
|
+
},
|
|
556
|
+
// ============================================
|
|
557
|
+
// PROPERTY ERC1155 FUNCTIONS
|
|
558
|
+
// ============================================
|
|
559
|
+
/**
|
|
560
|
+
* Get batch token balances for multiple accounts and token IDs
|
|
561
|
+
*/
|
|
562
|
+
async getBatchTokenBalances(propertyAddress, accounts, tokenIds, provider) {
|
|
563
|
+
if (accounts.length !== tokenIds.length) {
|
|
564
|
+
throw new Error("Accounts and tokenIds arrays must have the same length");
|
|
565
|
+
}
|
|
566
|
+
const { Contract } = await import("ethers");
|
|
567
|
+
const propertyContract = new Contract(propertyAddress, PROPERTY_ABI, provider);
|
|
568
|
+
const normalizedTokenIds = tokenIds.map(id => BigInt(id));
|
|
569
|
+
return await propertyContract.balanceOfBatch(accounts, normalizedTokenIds);
|
|
570
|
+
},
|
|
571
|
+
/**
|
|
572
|
+
* Transfer tokens from one address to another
|
|
573
|
+
*
|
|
574
|
+
* @param propertyAddress Property contract address
|
|
575
|
+
* @param from Sender address
|
|
576
|
+
* @param to Recipient address
|
|
577
|
+
* @param tokenId Token ID (usually 1 for PROPERTY_TOKEN_ID)
|
|
578
|
+
* @param amount Amount to transfer
|
|
579
|
+
* @param data Additional data (optional, can be empty bytes)
|
|
580
|
+
* @param signer Signer (must be the sender or approved operator)
|
|
581
|
+
* @returns Transaction hash
|
|
582
|
+
*/
|
|
583
|
+
async transferTokens(propertyAddress, from, to, tokenId, amount, signer, data = "0x") {
|
|
584
|
+
if (!to || to === "0x0000000000000000000000000000000000000000") {
|
|
585
|
+
throw new Error("Invalid recipient address");
|
|
586
|
+
}
|
|
587
|
+
const { Contract } = await import("ethers");
|
|
588
|
+
const propertyContract = new Contract(propertyAddress, PROPERTY_ABI, signer);
|
|
589
|
+
const normalizedAmount = toBigInt(amount);
|
|
590
|
+
if (normalizedAmount <= 0n) {
|
|
591
|
+
throw new Error("Transfer amount must be positive");
|
|
592
|
+
}
|
|
593
|
+
const tx = await propertyContract.safeTransferFrom(from, to, BigInt(tokenId), normalizedAmount, data);
|
|
594
|
+
const receipt = await tx.wait();
|
|
595
|
+
return receipt.hash || receipt.transactionHash;
|
|
596
|
+
},
|
|
597
|
+
/**
|
|
598
|
+
* Batch transfer tokens from one address to another
|
|
599
|
+
*
|
|
600
|
+
* @param propertyAddress Property contract address
|
|
601
|
+
* @param from Sender address
|
|
602
|
+
* @param to Recipient address
|
|
603
|
+
* @param tokenIds Array of token IDs
|
|
604
|
+
* @param amounts Array of amounts to transfer
|
|
605
|
+
* @param signer Signer (must be the sender or approved operator)
|
|
606
|
+
* @param data Additional data (optional, can be empty bytes)
|
|
607
|
+
* @returns Transaction hash
|
|
608
|
+
*/
|
|
609
|
+
async batchTransferTokens(propertyAddress, from, to, tokenIds, amounts, signer, data = "0x") {
|
|
610
|
+
if (tokenIds.length !== amounts.length) {
|
|
611
|
+
throw new Error("TokenIds and amounts arrays must have the same length");
|
|
612
|
+
}
|
|
613
|
+
if (!to || to === "0x0000000000000000000000000000000000000000") {
|
|
614
|
+
throw new Error("Invalid recipient address");
|
|
615
|
+
}
|
|
616
|
+
const { Contract } = await import("ethers");
|
|
617
|
+
const propertyContract = new Contract(propertyAddress, PROPERTY_ABI, signer);
|
|
618
|
+
const normalizedTokenIds = tokenIds.map(id => BigInt(id));
|
|
619
|
+
const normalizedAmounts = amounts.map(amt => toBigInt(amt));
|
|
620
|
+
const tx = await propertyContract.safeBatchTransferFrom(from, to, normalizedTokenIds, normalizedAmounts, data);
|
|
621
|
+
const receipt = await tx.wait();
|
|
622
|
+
return receipt.hash || receipt.transactionHash;
|
|
623
|
+
},
|
|
624
|
+
/**
|
|
625
|
+
* Approve or revoke operator approval for all tokens
|
|
626
|
+
*
|
|
627
|
+
* @param propertyAddress Property contract address
|
|
628
|
+
* @param operator Operator address to approve/revoke
|
|
629
|
+
* @param approved Whether to approve (true) or revoke (false)
|
|
630
|
+
* @param signer Signer (must be the token owner)
|
|
631
|
+
* @returns Transaction hash
|
|
632
|
+
*/
|
|
633
|
+
async setApprovalForAll(propertyAddress, operator, approved, signer) {
|
|
634
|
+
if (!operator || operator === "0x0000000000000000000000000000000000000000") {
|
|
635
|
+
throw new Error("Invalid operator address");
|
|
636
|
+
}
|
|
637
|
+
const { Contract } = await import("ethers");
|
|
638
|
+
const propertyContract = new Contract(propertyAddress, PROPERTY_ABI, signer);
|
|
639
|
+
const tx = await propertyContract.setApprovalForAll(operator, approved);
|
|
640
|
+
const receipt = await tx.wait();
|
|
641
|
+
return receipt.hash || receipt.transactionHash;
|
|
642
|
+
},
|
|
643
|
+
/**
|
|
644
|
+
* Check if an operator is approved for all tokens
|
|
645
|
+
*/
|
|
646
|
+
async isApprovedForAll(propertyAddress, account, operator, provider) {
|
|
647
|
+
const { Contract } = await import("ethers");
|
|
648
|
+
const propertyContract = new Contract(propertyAddress, PROPERTY_ABI, provider);
|
|
649
|
+
return await propertyContract.isApprovedForAll(account, operator);
|
|
650
|
+
},
|
|
651
|
+
/**
|
|
652
|
+
* Check if contract supports a specific interface (ERC165)
|
|
653
|
+
*/
|
|
654
|
+
async supportsInterface(propertyAddress, interfaceId, provider) {
|
|
655
|
+
const { Contract } = await import("ethers");
|
|
656
|
+
const propertyContract = new Contract(propertyAddress, PROPERTY_ABI, provider);
|
|
657
|
+
return await propertyContract.supportsInterface(interfaceId);
|
|
658
|
+
},
|
|
659
|
+
// ============================================
|
|
660
|
+
// PROPERTY OWNERSHIP FUNCTIONS
|
|
661
|
+
// ============================================
|
|
662
|
+
/**
|
|
663
|
+
* Get property owner address
|
|
664
|
+
*/
|
|
665
|
+
async getPropertyOwner(propertyAddress, provider) {
|
|
666
|
+
const { Contract } = await import("ethers");
|
|
667
|
+
const propertyContract = new Contract(propertyAddress, PROPERTY_ABI, provider);
|
|
668
|
+
return await propertyContract.owner();
|
|
669
|
+
},
|
|
670
|
+
/**
|
|
671
|
+
* Renounce property ownership (only owner)
|
|
672
|
+
*/
|
|
673
|
+
async renouncePropertyOwnership(propertyAddress, signer) {
|
|
674
|
+
const { Contract } = await import("ethers");
|
|
675
|
+
const propertyContract = new Contract(propertyAddress, PROPERTY_ABI, signer);
|
|
676
|
+
const tx = await propertyContract.renounceOwnership();
|
|
677
|
+
const receipt = await tx.wait();
|
|
678
|
+
return receipt.hash || receipt.transactionHash;
|
|
679
|
+
},
|
|
680
|
+
/**
|
|
681
|
+
* Transfer property ownership (only owner)
|
|
682
|
+
*/
|
|
683
|
+
async transferPropertyOwnership(propertyAddress, newOwner, signer) {
|
|
684
|
+
if (!newOwner || newOwner === "0x0000000000000000000000000000000000000000") {
|
|
685
|
+
throw new Error("Invalid new owner address");
|
|
686
|
+
}
|
|
687
|
+
const { Contract } = await import("ethers");
|
|
688
|
+
const propertyContract = new Contract(propertyAddress, PROPERTY_ABI, signer);
|
|
689
|
+
const tx = await propertyContract.transferOwnership(newOwner);
|
|
690
|
+
const receipt = await tx.wait();
|
|
691
|
+
return receipt.hash || receipt.transactionHash;
|
|
692
|
+
}
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* Default factory address (can be overridden)
|
|
697
|
+
*/
|
|
698
|
+
export const DEFAULT_FACTORY_ADDRESS = "0x7d7aF5715e5671e0E3126b2428Dc2629bD9061e3";
|
|
699
|
+
/**
|
|
700
|
+
* Create RWA client with default factory address
|
|
701
|
+
*/
|
|
702
|
+
export function createDefaultRWAClient(overrides) {
|
|
703
|
+
return createRWAClient({
|
|
704
|
+
factoryAddress: DEFAULT_FACTORY_ADDRESS,
|
|
705
|
+
...overrides
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
//# sourceMappingURL=rwa.js.map
|