@cmdoss/memwal-sdk 0.6.2 → 0.8.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/ARCHITECTURE.md +547 -547
- package/BENCHMARKS.md +238 -238
- package/README.md +310 -181
- package/dist/ai-sdk/tools.d.ts +2 -2
- package/dist/ai-sdk/tools.js +2 -2
- package/dist/client/ClientMemoryManager.js +2 -2
- package/dist/client/ClientMemoryManager.js.map +1 -1
- package/dist/client/PersonalDataWallet.d.ts.map +1 -1
- package/dist/client/SimplePDWClient.d.ts +29 -1
- package/dist/client/SimplePDWClient.d.ts.map +1 -1
- package/dist/client/SimplePDWClient.js +45 -13
- package/dist/client/SimplePDWClient.js.map +1 -1
- package/dist/client/namespaces/EmbeddingsNamespace.d.ts +1 -1
- package/dist/client/namespaces/EmbeddingsNamespace.js +1 -1
- package/dist/client/namespaces/MemoryNamespace.d.ts +31 -0
- package/dist/client/namespaces/MemoryNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/MemoryNamespace.js +272 -39
- package/dist/client/namespaces/MemoryNamespace.js.map +1 -1
- package/dist/client/namespaces/consolidated/AINamespace.d.ts +2 -2
- package/dist/client/namespaces/consolidated/AINamespace.js +2 -2
- package/dist/client/namespaces/consolidated/BlockchainNamespace.d.ts +12 -2
- package/dist/client/namespaces/consolidated/BlockchainNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/consolidated/BlockchainNamespace.js +62 -4
- package/dist/client/namespaces/consolidated/BlockchainNamespace.js.map +1 -1
- package/dist/client/namespaces/consolidated/StorageNamespace.d.ts +67 -2
- package/dist/client/namespaces/consolidated/StorageNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/consolidated/StorageNamespace.js +549 -16
- package/dist/client/namespaces/consolidated/StorageNamespace.js.map +1 -1
- package/dist/config/ConfigurationHelper.js +61 -61
- package/dist/config/defaults.js +2 -2
- package/dist/config/defaults.js.map +1 -1
- package/dist/graph/GraphService.js +21 -21
- package/dist/graph/GraphService.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/seal/EncryptionService.d.ts +9 -5
- package/dist/infrastructure/seal/EncryptionService.d.ts.map +1 -1
- package/dist/infrastructure/seal/EncryptionService.js +37 -15
- package/dist/infrastructure/seal/EncryptionService.js.map +1 -1
- package/dist/infrastructure/seal/SealService.d.ts +13 -5
- package/dist/infrastructure/seal/SealService.d.ts.map +1 -1
- package/dist/infrastructure/seal/SealService.js +36 -34
- package/dist/infrastructure/seal/SealService.js.map +1 -1
- package/dist/langchain/createPDWRAG.js +30 -30
- package/dist/retrieval/MemoryDecryptionPipeline.d.ts.map +1 -1
- package/dist/retrieval/MemoryDecryptionPipeline.js +2 -1
- package/dist/retrieval/MemoryDecryptionPipeline.js.map +1 -1
- package/dist/retrieval/MemoryRetrievalService.d.ts +31 -0
- package/dist/retrieval/MemoryRetrievalService.d.ts.map +1 -1
- package/dist/retrieval/MemoryRetrievalService.js +44 -4
- package/dist/retrieval/MemoryRetrievalService.js.map +1 -1
- package/dist/services/CapabilityService.d.ts.map +1 -1
- package/dist/services/CapabilityService.js +30 -14
- package/dist/services/CapabilityService.js.map +1 -1
- package/dist/services/CrossContextPermissionService.d.ts.map +1 -1
- package/dist/services/CrossContextPermissionService.js +9 -7
- package/dist/services/CrossContextPermissionService.js.map +1 -1
- package/dist/services/EmbeddingService.d.ts +28 -1
- package/dist/services/EmbeddingService.d.ts.map +1 -1
- package/dist/services/EmbeddingService.js +54 -0
- package/dist/services/EmbeddingService.js.map +1 -1
- package/dist/services/EncryptionService.d.ts.map +1 -1
- package/dist/services/EncryptionService.js +6 -5
- package/dist/services/EncryptionService.js.map +1 -1
- package/dist/services/GeminiAIService.js +309 -309
- package/dist/services/IndexManager.d.ts +5 -1
- package/dist/services/IndexManager.d.ts.map +1 -1
- package/dist/services/IndexManager.js +17 -40
- package/dist/services/IndexManager.js.map +1 -1
- package/dist/services/QueryService.js +1 -1
- package/dist/services/QueryService.js.map +1 -1
- package/dist/services/StorageService.d.ts +11 -0
- package/dist/services/StorageService.d.ts.map +1 -1
- package/dist/services/StorageService.js +73 -10
- package/dist/services/StorageService.js.map +1 -1
- package/dist/services/TransactionService.d.ts +20 -0
- package/dist/services/TransactionService.d.ts.map +1 -1
- package/dist/services/TransactionService.js +43 -0
- package/dist/services/TransactionService.js.map +1 -1
- package/dist/services/ViewService.js +2 -2
- package/dist/services/ViewService.js.map +1 -1
- package/dist/services/storage/QuiltBatchManager.d.ts +101 -1
- package/dist/services/storage/QuiltBatchManager.d.ts.map +1 -1
- package/dist/services/storage/QuiltBatchManager.js +410 -20
- package/dist/services/storage/QuiltBatchManager.js.map +1 -1
- package/dist/services/storage/index.d.ts +1 -1
- package/dist/services/storage/index.d.ts.map +1 -1
- package/dist/services/storage/index.js.map +1 -1
- package/dist/utils/LRUCache.d.ts +106 -0
- package/dist/utils/LRUCache.d.ts.map +1 -0
- package/dist/utils/LRUCache.js +281 -0
- package/dist/utils/LRUCache.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/memoryIndexOnChain.d.ts +212 -0
- package/dist/utils/memoryIndexOnChain.d.ts.map +1 -0
- package/dist/utils/memoryIndexOnChain.js +312 -0
- package/dist/utils/memoryIndexOnChain.js.map +1 -0
- package/dist/utils/rebuildIndexNode.d.ts +29 -0
- package/dist/utils/rebuildIndexNode.d.ts.map +1 -1
- package/dist/utils/rebuildIndexNode.js +366 -98
- package/dist/utils/rebuildIndexNode.js.map +1 -1
- package/dist/vector/HnswWasmService.d.ts +20 -5
- package/dist/vector/HnswWasmService.d.ts.map +1 -1
- package/dist/vector/HnswWasmService.js +73 -40
- package/dist/vector/HnswWasmService.js.map +1 -1
- package/dist/vector/IHnswService.d.ts +10 -1
- package/dist/vector/IHnswService.d.ts.map +1 -1
- package/dist/vector/IHnswService.js.map +1 -1
- package/dist/vector/NodeHnswService.d.ts +16 -0
- package/dist/vector/NodeHnswService.d.ts.map +1 -1
- package/dist/vector/NodeHnswService.js +84 -5
- package/dist/vector/NodeHnswService.js.map +1 -1
- package/dist/vector/createHnswService.d.ts +1 -1
- package/dist/vector/createHnswService.js +1 -1
- package/dist/vector/index.d.ts +1 -1
- package/dist/vector/index.js +1 -1
- package/package.json +157 -157
- package/src/access/PermissionService.ts +635 -635
- package/src/aggregation/AggregationService.ts +389 -389
- package/src/ai-sdk/PDWVectorStore.ts +715 -715
- package/src/ai-sdk/index.ts +65 -65
- package/src/ai-sdk/tools.ts +460 -460
- package/src/ai-sdk/types.ts +404 -404
- package/src/batch/BatchManager.ts +597 -597
- package/src/batch/BatchingService.ts +429 -429
- package/src/batch/MemoryProcessingCache.ts +492 -492
- package/src/batch/index.ts +30 -30
- package/src/browser.ts +200 -200
- package/src/client/ClientMemoryManager.ts +987 -987
- package/src/client/PersonalDataWallet.ts +345 -345
- package/src/client/SimplePDWClient.ts +1289 -1222
- package/src/client/factory.ts +154 -154
- package/src/client/namespaces/AnalyticsNamespace.ts +377 -377
- package/src/client/namespaces/BatchNamespace.ts +356 -356
- package/src/client/namespaces/CacheNamespace.ts +123 -123
- package/src/client/namespaces/CapabilityNamespace.ts +217 -217
- package/src/client/namespaces/ClassifyNamespace.ts +169 -169
- package/src/client/namespaces/ContextNamespace.ts +297 -297
- package/src/client/namespaces/EmbeddingsNamespace.ts +99 -99
- package/src/client/namespaces/EncryptionNamespace.ts +221 -221
- package/src/client/namespaces/GraphNamespace.ts +468 -468
- package/src/client/namespaces/IndexNamespace.ts +361 -361
- package/src/client/namespaces/MemoryNamespace.ts +1422 -1135
- package/src/client/namespaces/PermissionsNamespace.ts +254 -254
- package/src/client/namespaces/PipelineNamespace.ts +220 -220
- package/src/client/namespaces/SearchNamespace.ts +1049 -1049
- package/src/client/namespaces/StorageNamespace.ts +458 -458
- package/src/client/namespaces/TxNamespace.ts +260 -260
- package/src/client/namespaces/WalletNamespace.ts +243 -243
- package/src/client/namespaces/consolidated/AINamespace.ts +449 -449
- package/src/client/namespaces/consolidated/BlockchainNamespace.ts +607 -546
- package/src/client/namespaces/consolidated/SecurityNamespace.ts +648 -648
- package/src/client/namespaces/consolidated/StorageNamespace.ts +1141 -497
- package/src/client/namespaces/consolidated/index.ts +39 -39
- package/src/client/signers/KeypairSigner.ts +108 -108
- package/src/client/signers/UnifiedSigner.ts +110 -110
- package/src/client/signers/WalletAdapterSigner.ts +159 -159
- package/src/client/signers/index.ts +26 -26
- package/src/config/ConfigurationHelper.ts +412 -412
- package/src/config/defaults.ts +51 -51
- package/src/config/index.ts +8 -8
- package/src/config/validation.ts +70 -70
- package/src/core/index.ts +14 -14
- package/src/core/interfaces/IService.ts +307 -307
- package/src/core/interfaces/index.ts +8 -8
- package/src/core/types/capability.ts +297 -297
- package/src/core/types/index.ts +870 -870
- package/src/core/types/wallet.ts +270 -270
- package/src/core/types.ts +9 -9
- package/src/core/wallet.ts +222 -222
- package/src/embedding/index.ts +19 -19
- package/src/embedding/types.ts +357 -357
- package/src/errors/index.ts +602 -602
- package/src/errors/recovery.ts +461 -461
- package/src/errors/validation.ts +567 -567
- package/src/generated/pdw/capability.ts +319 -319
- package/src/graph/GraphService.ts +887 -887
- package/src/graph/KnowledgeGraphManager.ts +728 -728
- package/src/graph/index.ts +25 -25
- package/src/index.ts +498 -474
- package/src/infrastructure/index.ts +22 -22
- package/src/infrastructure/seal/EncryptionService.ts +628 -603
- package/src/infrastructure/seal/SealService.ts +613 -615
- package/src/infrastructure/seal/index.ts +9 -9
- package/src/infrastructure/sui/BlockchainManager.ts +627 -627
- package/src/infrastructure/sui/SuiService.ts +888 -888
- package/src/infrastructure/sui/index.ts +9 -9
- package/src/infrastructure/walrus/StorageManager.ts +604 -604
- package/src/infrastructure/walrus/WalrusStorageService.ts +612 -612
- package/src/infrastructure/walrus/index.ts +9 -9
- package/src/langchain/PDWEmbeddings.ts +145 -145
- package/src/langchain/PDWVectorStore.ts +456 -456
- package/src/langchain/createPDWRAG.ts +303 -303
- package/src/langchain/index.ts +47 -47
- package/src/permissions/ConsentRepository.browser.ts +249 -249
- package/src/permissions/ConsentRepository.ts +364 -364
- package/src/pipeline/MemoryPipeline.ts +862 -862
- package/src/pipeline/PipelineManager.ts +683 -683
- package/src/pipeline/index.ts +26 -26
- package/src/retrieval/AdvancedSearchService.ts +629 -629
- package/src/retrieval/MemoryAnalyticsService.ts +711 -711
- package/src/retrieval/MemoryDecryptionPipeline.ts +825 -824
- package/src/retrieval/MemoryRetrievalService.ts +904 -830
- package/src/retrieval/index.ts +42 -42
- package/src/services/BatchService.ts +352 -352
- package/src/services/CapabilityService.ts +464 -448
- package/src/services/ClassifierService.ts +465 -465
- package/src/services/CrossContextPermissionService.ts +486 -484
- package/src/services/EmbeddingService.ts +771 -706
- package/src/services/EncryptionService.ts +712 -711
- package/src/services/GeminiAIService.ts +753 -753
- package/src/services/IndexManager.ts +977 -1004
- package/src/services/MemoryIndexService.ts +1003 -1003
- package/src/services/MemoryService.ts +369 -369
- package/src/services/QueryService.ts +890 -890
- package/src/services/StorageService.ts +1182 -1111
- package/src/services/TransactionService.ts +838 -790
- package/src/services/VectorService.ts +462 -462
- package/src/services/ViewService.ts +484 -484
- package/src/services/index.ts +25 -25
- package/src/services/storage/BlobAttributesManager.ts +333 -333
- package/src/services/storage/KnowledgeGraphManager.ts +425 -425
- package/src/services/storage/MemorySearchManager.ts +387 -387
- package/src/services/storage/QuiltBatchManager.ts +1130 -660
- package/src/services/storage/WalrusMetadataManager.ts +268 -268
- package/src/services/storage/WalrusStorageManager.ts +287 -287
- package/src/services/storage/index.ts +57 -52
- package/src/types/index.ts +13 -13
- package/src/utils/LRUCache.ts +378 -0
- package/src/utils/index.ts +76 -68
- package/src/utils/memoryIndexOnChain.ts +507 -0
- package/src/utils/rebuildIndex.ts +290 -290
- package/src/utils/rebuildIndexNode.ts +771 -424
- package/src/vector/BrowserHnswIndexService.ts +758 -758
- package/src/vector/HnswWasmService.ts +731 -679
- package/src/vector/IHnswService.ts +233 -224
- package/src/vector/NodeHnswService.ts +833 -735
- package/src/vector/VectorManager.ts +478 -478
- package/src/vector/createHnswService.ts +135 -135
- package/src/vector/index.ts +56 -56
- package/src/wallet/ContextWalletService.ts +656 -656
- package/src/wallet/MainWalletService.ts +317 -317
|
@@ -1,484 +1,486 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cross-Context Permission Service
|
|
3
|
-
*
|
|
4
|
-
* Manages cross-context access permissions for the Personal Data Wallet.
|
|
5
|
-
* Enables apps to request and manage access to data from other app contexts.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { Transaction } from '@mysten/sui/transactions';
|
|
9
|
-
import { normalizeSuiAddress } from '@mysten/sui/utils';
|
|
10
|
-
import type { SuiClient } from '@mysten/sui/client';
|
|
11
|
-
import type { Signer } from '@mysten/sui/cryptography';
|
|
12
|
-
|
|
13
|
-
export interface CrossContextPermissionConfig {
|
|
14
|
-
packageId: string;
|
|
15
|
-
accessRegistryId: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface RegisterContextWalletOptions {
|
|
19
|
-
contextWallet: string;
|
|
20
|
-
derivationIndex: number;
|
|
21
|
-
appHint?: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface GrantWalletAllowlistOptions {
|
|
25
|
-
requestingWallet: string;
|
|
26
|
-
targetWallet: string;
|
|
27
|
-
scope?: string;
|
|
28
|
-
accessLevel: 'read' | 'write';
|
|
29
|
-
expiresAt: number; // Unix timestamp in milliseconds
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface RevokeWalletAllowlistOptions {
|
|
33
|
-
requestingWallet: string;
|
|
34
|
-
targetWallet: string;
|
|
35
|
-
scope?: string;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface WalletAllowlistPermission {
|
|
39
|
-
requestingWallet: string;
|
|
40
|
-
targetWallet: string;
|
|
41
|
-
scope: string;
|
|
42
|
-
accessLevel: string;
|
|
43
|
-
grantedAt: number;
|
|
44
|
-
expiresAt: number;
|
|
45
|
-
grantedBy: string;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export interface WalletAllowlistHistoryEvent {
|
|
49
|
-
timestamp: number;
|
|
50
|
-
action: 'grant' | 'revoke';
|
|
51
|
-
requestingWallet: string;
|
|
52
|
-
targetWallet: string;
|
|
53
|
-
scope: string;
|
|
54
|
-
accessLevel: string;
|
|
55
|
-
expiresAt: number;
|
|
56
|
-
grantedBy: string;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface WalletAllowlistHistoryFilter {
|
|
60
|
-
requestingWallet?: string;
|
|
61
|
-
targetWallet?: string;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export interface CheckWalletAccessOptions {
|
|
65
|
-
requestingWallet: string;
|
|
66
|
-
targetWallet?: string;
|
|
67
|
-
scope?: string;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
interface WalletAllowlistEvent {
|
|
71
|
-
key: string;
|
|
72
|
-
requestingWallet: string;
|
|
73
|
-
targetWallet: string;
|
|
74
|
-
scope: string;
|
|
75
|
-
accessLevel: string;
|
|
76
|
-
granted: boolean;
|
|
77
|
-
expiresAt: number;
|
|
78
|
-
grantedAt: number;
|
|
79
|
-
grantedBy: string;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Service for managing cross-context permissions
|
|
84
|
-
*/
|
|
85
|
-
export class CrossContextPermissionService {
|
|
86
|
-
private packageId: string;
|
|
87
|
-
private accessRegistryId: string;
|
|
88
|
-
private client: SuiClient;
|
|
89
|
-
|
|
90
|
-
constructor(config: CrossContextPermissionConfig, client: SuiClient) {
|
|
91
|
-
this.packageId = config.packageId;
|
|
92
|
-
this.accessRegistryId = config.accessRegistryId;
|
|
93
|
-
this.client = client;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Register a new context wallet for an app
|
|
98
|
-
*
|
|
99
|
-
* @param options - Context registration options
|
|
100
|
-
* @param signer - Transaction signer
|
|
101
|
-
* @returns Transaction digest
|
|
102
|
-
*/
|
|
103
|
-
async registerContextWallet(
|
|
104
|
-
options: RegisterContextWalletOptions,
|
|
105
|
-
signer: Signer
|
|
106
|
-
): Promise<string> {
|
|
107
|
-
const tx = this.buildRegisterContextWalletTransaction(options);
|
|
108
|
-
|
|
109
|
-
const result = await this.client.signAndExecuteTransaction({
|
|
110
|
-
transaction: tx,
|
|
111
|
-
signer,
|
|
112
|
-
options: {
|
|
113
|
-
showEffects: true,
|
|
114
|
-
showEvents: true,
|
|
115
|
-
},
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
// Wait for transaction to be finalized to prevent gas coin version conflicts
|
|
119
|
-
if (result.digest) {
|
|
120
|
-
await this.client.waitForTransaction({ digest: result.digest });
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (result.effects?.status?.status !== 'success') {
|
|
124
|
-
throw new Error(`Failed to register context: ${result.effects?.status?.error}`);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return result.digest;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Build transaction to register a context wallet
|
|
132
|
-
*
|
|
133
|
-
* @param options - Context registration options
|
|
134
|
-
* @returns Transaction object
|
|
135
|
-
*/
|
|
136
|
-
buildRegisterContextWalletTransaction(options: RegisterContextWalletOptions): Transaction {
|
|
137
|
-
const tx = new Transaction();
|
|
138
|
-
|
|
139
|
-
tx.moveCall({
|
|
140
|
-
target: `${this.packageId}::
|
|
141
|
-
arguments: [
|
|
142
|
-
tx.object(this.accessRegistryId),
|
|
143
|
-
tx.pure.address(normalizeSuiAddress(options.contextWallet)),
|
|
144
|
-
tx.pure.u64(options.derivationIndex),
|
|
145
|
-
tx.pure.string(options.appHint ?? ''),
|
|
146
|
-
tx.object('0x6'), // Clock object
|
|
147
|
-
],
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
return tx;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Grant cross-context access permission
|
|
155
|
-
*
|
|
156
|
-
* @param options - Permission grant options
|
|
157
|
-
* @param signer - Transaction signer
|
|
158
|
-
* @returns Transaction digest
|
|
159
|
-
*/
|
|
160
|
-
async grantWalletAllowlistAccess(
|
|
161
|
-
options: GrantWalletAllowlistOptions,
|
|
162
|
-
signer: Signer
|
|
163
|
-
): Promise<string> {
|
|
164
|
-
const tx = this.buildGrantWalletAllowlistTransaction(options);
|
|
165
|
-
|
|
166
|
-
const result = await this.client.signAndExecuteTransaction({
|
|
167
|
-
transaction: tx,
|
|
168
|
-
signer,
|
|
169
|
-
options: {
|
|
170
|
-
showEffects: true,
|
|
171
|
-
showEvents: true,
|
|
172
|
-
},
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
// Wait for transaction to be finalized to prevent gas coin version conflicts
|
|
176
|
-
if (result.digest) {
|
|
177
|
-
await this.client.waitForTransaction({ digest: result.digest });
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (result.effects?.status?.status !== 'success') {
|
|
181
|
-
throw new Error(`Failed to grant access: ${result.effects?.status?.error}`);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return result.digest;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Build transaction to grant cross-context access
|
|
189
|
-
*
|
|
190
|
-
* @param options - Permission grant options
|
|
191
|
-
* @returns Transaction object
|
|
192
|
-
*/
|
|
193
|
-
buildGrantWalletAllowlistTransaction(
|
|
194
|
-
options: GrantWalletAllowlistOptions
|
|
195
|
-
): Transaction {
|
|
196
|
-
const tx = new Transaction();
|
|
197
|
-
|
|
198
|
-
tx.moveCall({
|
|
199
|
-
target: `${this.packageId}::
|
|
200
|
-
arguments: [
|
|
201
|
-
tx.object(this.accessRegistryId),
|
|
202
|
-
tx.pure.address(normalizeSuiAddress(options.requestingWallet)),
|
|
203
|
-
tx.pure.address(normalizeSuiAddress(options.targetWallet)),
|
|
204
|
-
tx.pure.string(options.scope ?? 'read'),
|
|
205
|
-
tx.pure.string(options.accessLevel),
|
|
206
|
-
tx.pure.u64(options.expiresAt),
|
|
207
|
-
tx.object('0x6'), // Clock object
|
|
208
|
-
],
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
return tx;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Revoke cross-context access permission
|
|
216
|
-
*
|
|
217
|
-
* @param options - Permission revocation options
|
|
218
|
-
* @param signer - Transaction signer
|
|
219
|
-
* @returns Transaction digest
|
|
220
|
-
*/
|
|
221
|
-
async revokeWalletAllowlistAccess(
|
|
222
|
-
options: RevokeWalletAllowlistOptions,
|
|
223
|
-
signer: Signer
|
|
224
|
-
): Promise<string> {
|
|
225
|
-
const tx = this.buildRevokeWalletAllowlistTransaction(options);
|
|
226
|
-
|
|
227
|
-
const result = await this.client.signAndExecuteTransaction({
|
|
228
|
-
transaction: tx,
|
|
229
|
-
signer,
|
|
230
|
-
options: {
|
|
231
|
-
showEffects: true,
|
|
232
|
-
showEvents: true,
|
|
233
|
-
},
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
// Wait for transaction to be finalized to prevent gas coin version conflicts
|
|
237
|
-
if (result.digest) {
|
|
238
|
-
await this.client.waitForTransaction({ digest: result.digest });
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (result.effects?.status?.status !== 'success') {
|
|
242
|
-
throw new Error(`Failed to revoke access: ${result.effects?.status?.error}`);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
return result.digest;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Build transaction to revoke cross-context access
|
|
250
|
-
*
|
|
251
|
-
* @param options - Permission revocation options
|
|
252
|
-
* @returns Transaction object
|
|
253
|
-
*/
|
|
254
|
-
buildRevokeWalletAllowlistTransaction(
|
|
255
|
-
options: RevokeWalletAllowlistOptions
|
|
256
|
-
): Transaction {
|
|
257
|
-
const tx = new Transaction();
|
|
258
|
-
|
|
259
|
-
tx.moveCall({
|
|
260
|
-
target: `${this.packageId}::
|
|
261
|
-
arguments: [
|
|
262
|
-
tx.object(this.accessRegistryId),
|
|
263
|
-
tx.pure.address(normalizeSuiAddress(options.requestingWallet)),
|
|
264
|
-
tx.pure.address(normalizeSuiAddress(options.targetWallet)),
|
|
265
|
-
tx.pure.string(options.scope ?? 'read'),
|
|
266
|
-
],
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
return tx;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Build seal_approve transaction using capability module
|
|
274
|
-
*
|
|
275
|
-
* Uses pdw::capability::seal_approve which requires:
|
|
276
|
-
* - id: vector<u8> - SEAL key identifier (MUST be first parameter!)
|
|
277
|
-
* - cap: &MemoryCap - Reference to the capability object
|
|
278
|
-
*
|
|
279
|
-
* IMPORTANT: SEAL key server extracts 'id' from the FIRST PTB argument
|
|
280
|
-
*
|
|
281
|
-
* @param keyId - SEAL key ID bytes (computed from owner + nonce)
|
|
282
|
-
* @param memoryCapId - MemoryCap object ID on Sui
|
|
283
|
-
* @returns Transaction object
|
|
284
|
-
*/
|
|
285
|
-
buildSealApproveTransaction(
|
|
286
|
-
keyId: Uint8Array,
|
|
287
|
-
memoryCapId: string
|
|
288
|
-
): Transaction {
|
|
289
|
-
const tx = new Transaction();
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
tx
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
tx.
|
|
318
|
-
tx.
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
const
|
|
333
|
-
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
const
|
|
438
|
-
const
|
|
439
|
-
const
|
|
440
|
-
const
|
|
441
|
-
const
|
|
442
|
-
const
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
const
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Cross-Context Permission Service
|
|
3
|
+
*
|
|
4
|
+
* Manages cross-context access permissions for the Personal Data Wallet.
|
|
5
|
+
* Enables apps to request and manage access to data from other app contexts.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Transaction } from '@mysten/sui/transactions';
|
|
9
|
+
import { normalizeSuiAddress } from '@mysten/sui/utils';
|
|
10
|
+
import type { SuiClient } from '@mysten/sui/client';
|
|
11
|
+
import type { Signer } from '@mysten/sui/cryptography';
|
|
12
|
+
|
|
13
|
+
export interface CrossContextPermissionConfig {
|
|
14
|
+
packageId: string;
|
|
15
|
+
accessRegistryId: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface RegisterContextWalletOptions {
|
|
19
|
+
contextWallet: string;
|
|
20
|
+
derivationIndex: number;
|
|
21
|
+
appHint?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface GrantWalletAllowlistOptions {
|
|
25
|
+
requestingWallet: string;
|
|
26
|
+
targetWallet: string;
|
|
27
|
+
scope?: string;
|
|
28
|
+
accessLevel: 'read' | 'write';
|
|
29
|
+
expiresAt: number; // Unix timestamp in milliseconds
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface RevokeWalletAllowlistOptions {
|
|
33
|
+
requestingWallet: string;
|
|
34
|
+
targetWallet: string;
|
|
35
|
+
scope?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface WalletAllowlistPermission {
|
|
39
|
+
requestingWallet: string;
|
|
40
|
+
targetWallet: string;
|
|
41
|
+
scope: string;
|
|
42
|
+
accessLevel: string;
|
|
43
|
+
grantedAt: number;
|
|
44
|
+
expiresAt: number;
|
|
45
|
+
grantedBy: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface WalletAllowlistHistoryEvent {
|
|
49
|
+
timestamp: number;
|
|
50
|
+
action: 'grant' | 'revoke';
|
|
51
|
+
requestingWallet: string;
|
|
52
|
+
targetWallet: string;
|
|
53
|
+
scope: string;
|
|
54
|
+
accessLevel: string;
|
|
55
|
+
expiresAt: number;
|
|
56
|
+
grantedBy: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface WalletAllowlistHistoryFilter {
|
|
60
|
+
requestingWallet?: string;
|
|
61
|
+
targetWallet?: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface CheckWalletAccessOptions {
|
|
65
|
+
requestingWallet: string;
|
|
66
|
+
targetWallet?: string;
|
|
67
|
+
scope?: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
interface WalletAllowlistEvent {
|
|
71
|
+
key: string;
|
|
72
|
+
requestingWallet: string;
|
|
73
|
+
targetWallet: string;
|
|
74
|
+
scope: string;
|
|
75
|
+
accessLevel: string;
|
|
76
|
+
granted: boolean;
|
|
77
|
+
expiresAt: number;
|
|
78
|
+
grantedAt: number;
|
|
79
|
+
grantedBy: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Service for managing cross-context permissions
|
|
84
|
+
*/
|
|
85
|
+
export class CrossContextPermissionService {
|
|
86
|
+
private packageId: string;
|
|
87
|
+
private accessRegistryId: string;
|
|
88
|
+
private client: SuiClient;
|
|
89
|
+
|
|
90
|
+
constructor(config: CrossContextPermissionConfig, client: SuiClient) {
|
|
91
|
+
this.packageId = config.packageId;
|
|
92
|
+
this.accessRegistryId = config.accessRegistryId;
|
|
93
|
+
this.client = client;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Register a new context wallet for an app
|
|
98
|
+
*
|
|
99
|
+
* @param options - Context registration options
|
|
100
|
+
* @param signer - Transaction signer
|
|
101
|
+
* @returns Transaction digest
|
|
102
|
+
*/
|
|
103
|
+
async registerContextWallet(
|
|
104
|
+
options: RegisterContextWalletOptions,
|
|
105
|
+
signer: Signer
|
|
106
|
+
): Promise<string> {
|
|
107
|
+
const tx = this.buildRegisterContextWalletTransaction(options);
|
|
108
|
+
|
|
109
|
+
const result = await this.client.signAndExecuteTransaction({
|
|
110
|
+
transaction: tx,
|
|
111
|
+
signer,
|
|
112
|
+
options: {
|
|
113
|
+
showEffects: true,
|
|
114
|
+
showEvents: true,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// Wait for transaction to be finalized to prevent gas coin version conflicts
|
|
119
|
+
if (result.digest) {
|
|
120
|
+
await this.client.waitForTransaction({ digest: result.digest });
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (result.effects?.status?.status !== 'success') {
|
|
124
|
+
throw new Error(`Failed to register context: ${result.effects?.status?.error}`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return result.digest;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Build transaction to register a context wallet
|
|
132
|
+
*
|
|
133
|
+
* @param options - Context registration options
|
|
134
|
+
* @returns Transaction object
|
|
135
|
+
*/
|
|
136
|
+
buildRegisterContextWalletTransaction(options: RegisterContextWalletOptions): Transaction {
|
|
137
|
+
const tx = new Transaction();
|
|
138
|
+
|
|
139
|
+
tx.moveCall({
|
|
140
|
+
target: `${this.packageId}::capability::register_context_wallet`,
|
|
141
|
+
arguments: [
|
|
142
|
+
tx.object(this.accessRegistryId),
|
|
143
|
+
tx.pure.address(normalizeSuiAddress(options.contextWallet)),
|
|
144
|
+
tx.pure.u64(options.derivationIndex),
|
|
145
|
+
tx.pure.string(options.appHint ?? ''),
|
|
146
|
+
tx.object('0x6'), // Clock object
|
|
147
|
+
],
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
return tx;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Grant cross-context access permission
|
|
155
|
+
*
|
|
156
|
+
* @param options - Permission grant options
|
|
157
|
+
* @param signer - Transaction signer
|
|
158
|
+
* @returns Transaction digest
|
|
159
|
+
*/
|
|
160
|
+
async grantWalletAllowlistAccess(
|
|
161
|
+
options: GrantWalletAllowlistOptions,
|
|
162
|
+
signer: Signer
|
|
163
|
+
): Promise<string> {
|
|
164
|
+
const tx = this.buildGrantWalletAllowlistTransaction(options);
|
|
165
|
+
|
|
166
|
+
const result = await this.client.signAndExecuteTransaction({
|
|
167
|
+
transaction: tx,
|
|
168
|
+
signer,
|
|
169
|
+
options: {
|
|
170
|
+
showEffects: true,
|
|
171
|
+
showEvents: true,
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Wait for transaction to be finalized to prevent gas coin version conflicts
|
|
176
|
+
if (result.digest) {
|
|
177
|
+
await this.client.waitForTransaction({ digest: result.digest });
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (result.effects?.status?.status !== 'success') {
|
|
181
|
+
throw new Error(`Failed to grant access: ${result.effects?.status?.error}`);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return result.digest;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Build transaction to grant cross-context access
|
|
189
|
+
*
|
|
190
|
+
* @param options - Permission grant options
|
|
191
|
+
* @returns Transaction object
|
|
192
|
+
*/
|
|
193
|
+
buildGrantWalletAllowlistTransaction(
|
|
194
|
+
options: GrantWalletAllowlistOptions
|
|
195
|
+
): Transaction {
|
|
196
|
+
const tx = new Transaction();
|
|
197
|
+
|
|
198
|
+
tx.moveCall({
|
|
199
|
+
target: `${this.packageId}::capability::grant_wallet_allowlist_access`,
|
|
200
|
+
arguments: [
|
|
201
|
+
tx.object(this.accessRegistryId),
|
|
202
|
+
tx.pure.address(normalizeSuiAddress(options.requestingWallet)),
|
|
203
|
+
tx.pure.address(normalizeSuiAddress(options.targetWallet)),
|
|
204
|
+
tx.pure.string(options.scope ?? 'read'),
|
|
205
|
+
tx.pure.string(options.accessLevel),
|
|
206
|
+
tx.pure.u64(options.expiresAt),
|
|
207
|
+
tx.object('0x6'), // Clock object
|
|
208
|
+
],
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
return tx;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Revoke cross-context access permission
|
|
216
|
+
*
|
|
217
|
+
* @param options - Permission revocation options
|
|
218
|
+
* @param signer - Transaction signer
|
|
219
|
+
* @returns Transaction digest
|
|
220
|
+
*/
|
|
221
|
+
async revokeWalletAllowlistAccess(
|
|
222
|
+
options: RevokeWalletAllowlistOptions,
|
|
223
|
+
signer: Signer
|
|
224
|
+
): Promise<string> {
|
|
225
|
+
const tx = this.buildRevokeWalletAllowlistTransaction(options);
|
|
226
|
+
|
|
227
|
+
const result = await this.client.signAndExecuteTransaction({
|
|
228
|
+
transaction: tx,
|
|
229
|
+
signer,
|
|
230
|
+
options: {
|
|
231
|
+
showEffects: true,
|
|
232
|
+
showEvents: true,
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// Wait for transaction to be finalized to prevent gas coin version conflicts
|
|
237
|
+
if (result.digest) {
|
|
238
|
+
await this.client.waitForTransaction({ digest: result.digest });
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (result.effects?.status?.status !== 'success') {
|
|
242
|
+
throw new Error(`Failed to revoke access: ${result.effects?.status?.error}`);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return result.digest;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Build transaction to revoke cross-context access
|
|
250
|
+
*
|
|
251
|
+
* @param options - Permission revocation options
|
|
252
|
+
* @returns Transaction object
|
|
253
|
+
*/
|
|
254
|
+
buildRevokeWalletAllowlistTransaction(
|
|
255
|
+
options: RevokeWalletAllowlistOptions
|
|
256
|
+
): Transaction {
|
|
257
|
+
const tx = new Transaction();
|
|
258
|
+
|
|
259
|
+
tx.moveCall({
|
|
260
|
+
target: `${this.packageId}::capability::revoke_wallet_allowlist_access`,
|
|
261
|
+
arguments: [
|
|
262
|
+
tx.object(this.accessRegistryId),
|
|
263
|
+
tx.pure.address(normalizeSuiAddress(options.requestingWallet)),
|
|
264
|
+
tx.pure.address(normalizeSuiAddress(options.targetWallet)),
|
|
265
|
+
tx.pure.string(options.scope ?? 'read'),
|
|
266
|
+
],
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
return tx;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Build seal_approve transaction using capability module
|
|
274
|
+
*
|
|
275
|
+
* Uses pdw::capability::seal_approve which requires:
|
|
276
|
+
* - id: vector<u8> - SEAL key identifier (MUST be first parameter!)
|
|
277
|
+
* - cap: &MemoryCap - Reference to the capability object
|
|
278
|
+
*
|
|
279
|
+
* IMPORTANT: SEAL key server extracts 'id' from the FIRST PTB argument
|
|
280
|
+
*
|
|
281
|
+
* @param keyId - SEAL key ID bytes (computed from owner + nonce)
|
|
282
|
+
* @param memoryCapId - MemoryCap object ID on Sui
|
|
283
|
+
* @returns Transaction object
|
|
284
|
+
*/
|
|
285
|
+
buildSealApproveTransaction(
|
|
286
|
+
keyId: Uint8Array,
|
|
287
|
+
memoryCapId: string
|
|
288
|
+
): Transaction {
|
|
289
|
+
const tx = new Transaction();
|
|
290
|
+
|
|
291
|
+
// CRITICAL: key_id MUST be first argument!
|
|
292
|
+
// SEAL key server extracts 'id' from the FIRST PTB argument for decryption approval.
|
|
293
|
+
tx.moveCall({
|
|
294
|
+
target: `${this.packageId}::capability::seal_approve`,
|
|
295
|
+
arguments: [
|
|
296
|
+
tx.pure.vector('u8', Array.from(keyId)), // Arg 1: key_id bytes (SEAL key server requirement!)
|
|
297
|
+
tx.object(memoryCapId), // Arg 2: MemoryCap reference
|
|
298
|
+
],
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
return tx;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Build seal_approve transaction (legacy - for backward compatibility)
|
|
306
|
+
* @deprecated Use buildSealApproveTransaction with memoryCapId instead
|
|
307
|
+
*/
|
|
308
|
+
buildSealApproveTransactionLegacy(
|
|
309
|
+
contentId: Uint8Array,
|
|
310
|
+
requestingWallet: string
|
|
311
|
+
): Transaction {
|
|
312
|
+
const tx = new Transaction();
|
|
313
|
+
|
|
314
|
+
tx.moveCall({
|
|
315
|
+
target: `${this.packageId}::capability::seal_approve`,
|
|
316
|
+
arguments: [
|
|
317
|
+
tx.pure.vector('u8', Array.from(contentId)),
|
|
318
|
+
tx.pure.address(normalizeSuiAddress(requestingWallet)),
|
|
319
|
+
tx.object(this.accessRegistryId),
|
|
320
|
+
tx.object('0x6'), // Clock object
|
|
321
|
+
],
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
return tx;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Query wallet allowlist permissions filtered by requester, target, or scope
|
|
329
|
+
*/
|
|
330
|
+
async queryWalletPermissions(options: Partial<CheckWalletAccessOptions>): Promise<WalletAllowlistPermission[]> {
|
|
331
|
+
const events = await this.fetchWalletAllowlistEvents();
|
|
332
|
+
const state = this.reduceWalletAllowlistEvents(events);
|
|
333
|
+
|
|
334
|
+
const normalizedRequester = options.requestingWallet ? normalizeSuiAddress(options.requestingWallet) : undefined;
|
|
335
|
+
const normalizedTarget = options.targetWallet ? normalizeSuiAddress(options.targetWallet) : undefined;
|
|
336
|
+
const scopeFilter = options.scope ?? undefined;
|
|
337
|
+
|
|
338
|
+
return Array.from(state.values())
|
|
339
|
+
.filter((permission) => {
|
|
340
|
+
if (normalizedRequester && permission.requestingWallet !== normalizedRequester) {
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
if (normalizedTarget && permission.targetWallet !== normalizedTarget) {
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
if (scopeFilter && permission.scope !== scopeFilter) {
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
return true;
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
async listGrantsByTarget(targetWallet: string, scope?: string): Promise<WalletAllowlistPermission[]> {
|
|
354
|
+
return this.queryWalletPermissions({ targetWallet, scope });
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
async listGrantsByRequester(requestingWallet: string, scope?: string): Promise<WalletAllowlistPermission[]> {
|
|
358
|
+
return this.queryWalletPermissions({ requestingWallet, scope });
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Determine whether a wallet currently has allowlist permission
|
|
363
|
+
*/
|
|
364
|
+
async hasWalletPermission(options: CheckWalletAccessOptions): Promise<boolean> {
|
|
365
|
+
const permissions = await this.queryWalletPermissions(options);
|
|
366
|
+
const now = Date.now();
|
|
367
|
+
|
|
368
|
+
return permissions.some(permission => {
|
|
369
|
+
const expiry = permission.expiresAt;
|
|
370
|
+
return expiry === 0 || expiry > now;
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* List target wallets this requester can access for an optional scope
|
|
376
|
+
*/
|
|
377
|
+
async getAccessibleWallets(requestingWallet: string, scope: string = 'read'): Promise<string[]> {
|
|
378
|
+
const permissions = await this.queryWalletPermissions({ requestingWallet, scope });
|
|
379
|
+
const now = Date.now();
|
|
380
|
+
|
|
381
|
+
return permissions
|
|
382
|
+
.filter(permission => permission.expiresAt === 0 || permission.expiresAt > now)
|
|
383
|
+
.map(permission => permission.targetWallet);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
async getWalletAllowlistHistory(
|
|
387
|
+
filter?: WalletAllowlistHistoryFilter,
|
|
388
|
+
): Promise<WalletAllowlistHistoryEvent[]> {
|
|
389
|
+
const events = await this.fetchWalletAllowlistEvents();
|
|
390
|
+
const normalizedRequester = filter?.requestingWallet
|
|
391
|
+
? normalizeSuiAddress(filter.requestingWallet)
|
|
392
|
+
: undefined;
|
|
393
|
+
const normalizedTarget = filter?.targetWallet
|
|
394
|
+
? normalizeSuiAddress(filter.targetWallet)
|
|
395
|
+
: undefined;
|
|
396
|
+
|
|
397
|
+
return events
|
|
398
|
+
.filter((event) => {
|
|
399
|
+
if (normalizedRequester && event.requestingWallet !== normalizedRequester) {
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
if (normalizedTarget && event.targetWallet !== normalizedTarget) {
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
return true;
|
|
406
|
+
})
|
|
407
|
+
.map<WalletAllowlistHistoryEvent>((event) => ({
|
|
408
|
+
timestamp: event.grantedAt,
|
|
409
|
+
action: event.granted ? 'grant' : 'revoke',
|
|
410
|
+
requestingWallet: event.requestingWallet,
|
|
411
|
+
targetWallet: event.targetWallet,
|
|
412
|
+
scope: event.scope,
|
|
413
|
+
accessLevel: event.accessLevel,
|
|
414
|
+
expiresAt: event.expiresAt,
|
|
415
|
+
grantedBy: event.grantedBy,
|
|
416
|
+
}))
|
|
417
|
+
.sort((a, b) => a.timestamp - b.timestamp);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
private async fetchWalletAllowlistEvents(): Promise<WalletAllowlistEvent[]> {
|
|
421
|
+
const response = await this.client.queryEvents({
|
|
422
|
+
query: {
|
|
423
|
+
MoveEventType: `${this.packageId}::capability::WalletAllowlistChanged`,
|
|
424
|
+
},
|
|
425
|
+
limit: 1000,
|
|
426
|
+
order: 'ascending',
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
const events: WalletAllowlistEvent[] = [];
|
|
430
|
+
|
|
431
|
+
for (const event of response.data) {
|
|
432
|
+
const parsed = event.parsedJson as any;
|
|
433
|
+
if (!parsed) {
|
|
434
|
+
continue;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const requestingWallet = normalizeSuiAddress(String(parsed.requester_wallet));
|
|
438
|
+
const targetWallet = normalizeSuiAddress(String(parsed.target_wallet));
|
|
439
|
+
const scope = String(parsed.scope ?? 'read');
|
|
440
|
+
const accessLevel = String(parsed.access_level ?? 'read');
|
|
441
|
+
const granted = Boolean(parsed.granted);
|
|
442
|
+
const expiresAt = Number(parsed.expires_at ?? 0);
|
|
443
|
+
const grantedBy = normalizeSuiAddress(String(parsed.granted_by ?? requestingWallet));
|
|
444
|
+
const grantedAt = Number(event.timestampMs ?? Date.now());
|
|
445
|
+
const key = `${requestingWallet}-${targetWallet}-${scope}`;
|
|
446
|
+
|
|
447
|
+
events.push({
|
|
448
|
+
key,
|
|
449
|
+
requestingWallet,
|
|
450
|
+
targetWallet,
|
|
451
|
+
scope,
|
|
452
|
+
accessLevel,
|
|
453
|
+
granted,
|
|
454
|
+
expiresAt,
|
|
455
|
+
grantedAt,
|
|
456
|
+
grantedBy,
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
return events;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
private reduceWalletAllowlistEvents(events: WalletAllowlistEvent[]): Map<string, WalletAllowlistPermission> {
|
|
464
|
+
const state = new Map<string, WalletAllowlistPermission>();
|
|
465
|
+
|
|
466
|
+
const sorted = [...events].sort((a, b) => a.grantedAt - b.grantedAt);
|
|
467
|
+
|
|
468
|
+
for (const event of sorted) {
|
|
469
|
+
if (event.granted) {
|
|
470
|
+
state.set(event.key, {
|
|
471
|
+
requestingWallet: event.requestingWallet,
|
|
472
|
+
targetWallet: event.targetWallet,
|
|
473
|
+
scope: event.scope,
|
|
474
|
+
accessLevel: event.accessLevel,
|
|
475
|
+
grantedAt: event.grantedAt,
|
|
476
|
+
expiresAt: event.expiresAt,
|
|
477
|
+
grantedBy: event.grantedBy,
|
|
478
|
+
});
|
|
479
|
+
} else {
|
|
480
|
+
state.delete(event.key);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
return state;
|
|
485
|
+
}
|
|
486
|
+
}
|