@opendatalabs/vana-sdk 0.1.0-alpha.a6b60fc → 0.1.0-alpha.a78ce5c
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/dist/client/__tests__/enhancedResponse.test.d.ts +1 -0
- package/dist/client/enhancedResponse.cjs +164 -0
- package/dist/client/enhancedResponse.cjs.map +1 -0
- package/dist/client/enhancedResponse.d.ts +120 -0
- package/dist/client/enhancedResponse.js +138 -0
- package/dist/client/enhancedResponse.js.map +1 -0
- package/dist/controllers/__tests__/data-consistency-integration.test.d.ts +7 -0
- package/dist/controllers/__tests__/operations.processQueue.test.d.ts +1 -0
- package/dist/controllers/base.cjs +33 -0
- package/dist/controllers/base.cjs.map +1 -1
- package/dist/controllers/base.d.ts +10 -0
- package/dist/controllers/base.js +33 -0
- package/dist/controllers/base.js.map +1 -1
- package/dist/controllers/data.cjs +278 -159
- package/dist/controllers/data.cjs.map +1 -1
- package/dist/controllers/data.d.ts +34 -19
- package/dist/controllers/data.js +291 -162
- package/dist/controllers/data.js.map +1 -1
- package/dist/controllers/operations.cjs +430 -0
- package/dist/controllers/operations.cjs.map +1 -0
- package/dist/controllers/operations.d.ts +229 -0
- package/dist/controllers/operations.js +406 -0
- package/dist/controllers/operations.js.map +1 -0
- package/dist/controllers/permissions.cjs +605 -213
- package/dist/controllers/permissions.cjs.map +1 -1
- package/dist/controllers/permissions.d.ts +141 -34
- package/dist/controllers/permissions.js +605 -213
- package/dist/controllers/permissions.js.map +1 -1
- package/dist/controllers/schemas.cjs +81 -4
- package/dist/controllers/schemas.cjs.map +1 -1
- package/dist/controllers/schemas.d.ts +41 -0
- package/dist/controllers/schemas.js +81 -4
- package/dist/controllers/schemas.js.map +1 -1
- package/dist/controllers/server.cjs +251 -42
- package/dist/controllers/server.cjs.map +1 -1
- package/dist/controllers/server.d.ts +111 -14
- package/dist/controllers/server.js +251 -42
- package/dist/controllers/server.js.map +1 -1
- package/dist/core/__tests__/health.test.d.ts +1 -0
- package/dist/core/__tests__/inMemoryNonceManager.test.d.ts +1 -0
- package/dist/core/__tests__/nonceManager.test.d.ts +1 -0
- package/dist/core/__tests__/pollingManager.test.d.ts +4 -0
- package/dist/core/health.cjs +289 -0
- package/dist/core/health.cjs.map +1 -0
- package/dist/core/health.d.ts +143 -0
- package/dist/core/health.js +265 -0
- package/dist/core/health.js.map +1 -0
- package/dist/core/inMemoryNonceManager.cjs +138 -0
- package/dist/core/inMemoryNonceManager.cjs.map +1 -0
- package/dist/core/inMemoryNonceManager.d.ts +69 -0
- package/dist/core/inMemoryNonceManager.js +114 -0
- package/dist/core/inMemoryNonceManager.js.map +1 -0
- package/dist/core/nonceManager.cjs +304 -0
- package/dist/core/nonceManager.cjs.map +1 -0
- package/dist/core/nonceManager.d.ts +116 -0
- package/dist/core/nonceManager.js +280 -0
- package/dist/core/nonceManager.js.map +1 -0
- package/dist/core/pollingManager.cjs +292 -0
- package/dist/core/pollingManager.cjs.map +1 -0
- package/dist/core/pollingManager.d.ts +120 -0
- package/dist/core/pollingManager.js +268 -0
- package/dist/core/pollingManager.js.map +1 -0
- package/dist/core.cjs +55 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.ts +54 -3
- package/dist/core.js +55 -1
- package/dist/core.js.map +1 -1
- package/dist/crypto/ecies/base.cjs +16 -3
- package/dist/crypto/ecies/base.cjs.map +1 -1
- package/dist/crypto/ecies/base.js +16 -3
- package/dist/crypto/ecies/base.js.map +1 -1
- package/dist/errors.cjs +29 -0
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +64 -0
- package/dist/errors.js +28 -0
- package/dist/errors.js.map +1 -1
- package/dist/generated/abi/ComputeInstructionRegistryImplementation.cjs.map +1 -1
- package/dist/generated/abi/ComputeInstructionRegistryImplementation.js.map +1 -1
- package/dist/generated/abi/DLPPerformanceImplementation.cjs +42 -0
- package/dist/generated/abi/DLPPerformanceImplementation.cjs.map +1 -1
- package/dist/generated/abi/DLPPerformanceImplementation.d.ts +32 -0
- package/dist/generated/abi/DLPPerformanceImplementation.js +42 -0
- package/dist/generated/abi/DLPPerformanceImplementation.js.map +1 -1
- package/dist/generated/abi/DLPRegistryImplementation.cjs +5 -5
- package/dist/generated/abi/DLPRegistryImplementation.cjs.map +1 -1
- package/dist/generated/abi/DLPRegistryImplementation.d.ts +4 -4
- package/dist/generated/abi/DLPRegistryImplementation.js +5 -5
- package/dist/generated/abi/DLPRegistryImplementation.js.map +1 -1
- package/dist/generated/abi/DLPRewardDeployerImplementation.cjs +166 -2
- package/dist/generated/abi/DLPRewardDeployerImplementation.cjs.map +1 -1
- package/dist/generated/abi/DLPRewardDeployerImplementation.d.ts +129 -2
- package/dist/generated/abi/DLPRewardDeployerImplementation.js +166 -2
- package/dist/generated/abi/DLPRewardDeployerImplementation.js.map +1 -1
- package/dist/generated/abi/DataPortabilityGranteesImplementation.cjs +167 -19
- package/dist/generated/abi/DataPortabilityGranteesImplementation.cjs.map +1 -1
- package/dist/generated/abi/DataPortabilityGranteesImplementation.d.ts +127 -14
- package/dist/generated/abi/DataPortabilityGranteesImplementation.js +167 -19
- package/dist/generated/abi/DataPortabilityGranteesImplementation.js.map +1 -1
- package/dist/generated/abi/DataPortabilityPermissionsImplementation.cjs +0 -19
- package/dist/generated/abi/DataPortabilityPermissionsImplementation.cjs.map +1 -1
- package/dist/generated/abi/DataPortabilityPermissionsImplementation.d.ts +0 -14
- package/dist/generated/abi/DataPortabilityPermissionsImplementation.js +0 -19
- package/dist/generated/abi/DataPortabilityPermissionsImplementation.js.map +1 -1
- package/dist/generated/abi/DataPortabilityServersImplementation.cjs +0 -19
- package/dist/generated/abi/DataPortabilityServersImplementation.cjs.map +1 -1
- package/dist/generated/abi/DataPortabilityServersImplementation.d.ts +0 -14
- package/dist/generated/abi/DataPortabilityServersImplementation.js +0 -19
- package/dist/generated/abi/DataPortabilityServersImplementation.js.map +1 -1
- package/dist/generated/abi/DataRegistryImplementation.cjs +0 -13
- package/dist/generated/abi/DataRegistryImplementation.cjs.map +1 -1
- package/dist/generated/abi/DataRegistryImplementation.d.ts +0 -10
- package/dist/generated/abi/DataRegistryImplementation.js +0 -13
- package/dist/generated/abi/DataRegistryImplementation.js.map +1 -1
- package/dist/generated/abi/SwapHelperImplementation.cjs +0 -43
- package/dist/generated/abi/SwapHelperImplementation.cjs.map +1 -1
- package/dist/generated/abi/SwapHelperImplementation.d.ts +0 -35
- package/dist/generated/abi/SwapHelperImplementation.js +0 -43
- package/dist/generated/abi/SwapHelperImplementation.js.map +1 -1
- package/dist/generated/abi/VanaEpochImplementation.cjs +195 -0
- package/dist/generated/abi/VanaEpochImplementation.cjs.map +1 -1
- package/dist/generated/abi/VanaEpochImplementation.d.ts +151 -0
- package/dist/generated/abi/VanaEpochImplementation.js +195 -0
- package/dist/generated/abi/VanaEpochImplementation.js.map +1 -1
- package/dist/generated/abi/VanaPoolEntityImplementation.cjs +22 -65
- package/dist/generated/abi/VanaPoolEntityImplementation.cjs.map +1 -1
- package/dist/generated/abi/VanaPoolEntityImplementation.d.ts +17 -51
- package/dist/generated/abi/VanaPoolEntityImplementation.js +22 -65
- package/dist/generated/abi/VanaPoolEntityImplementation.js.map +1 -1
- package/dist/generated/abi/VanaPoolStakingImplementation.cjs +113 -1
- package/dist/generated/abi/VanaPoolStakingImplementation.cjs.map +1 -1
- package/dist/generated/abi/VanaPoolStakingImplementation.d.ts +85 -1
- package/dist/generated/abi/VanaPoolStakingImplementation.js +113 -1
- package/dist/generated/abi/VanaPoolStakingImplementation.js.map +1 -1
- package/dist/generated/abi/index.d.ts +546 -146
- package/dist/generated/event-types.cjs.map +1 -1
- package/dist/generated/event-types.d.ts +14 -8
- package/dist/generated/eventRegistry.cjs +42 -18
- package/dist/generated/eventRegistry.cjs.map +1 -1
- package/dist/generated/eventRegistry.js +42 -18
- package/dist/generated/eventRegistry.js.map +1 -1
- package/dist/generated/server/server-exports.cjs +22 -0
- package/dist/generated/server/server-exports.cjs.map +1 -1
- package/dist/generated/server/server-exports.d.ts +27 -10
- package/dist/generated/server/server-exports.js +17 -0
- package/dist/generated/server/server-exports.js.map +1 -1
- package/dist/generated/server/server.cjs.map +1 -1
- package/dist/generated/server/server.d.ts +771 -402
- package/dist/generated/subgraph.cjs +797 -32
- package/dist/generated/subgraph.cjs.map +1 -1
- package/dist/generated/subgraph.d.ts +135 -0
- package/dist/generated/subgraph.js +792 -32
- package/dist/generated/subgraph.js.map +1 -1
- package/dist/index.browser.d.ts +2 -0
- package/dist/index.browser.js +10 -0
- package/dist/index.browser.js.map +1 -1
- package/dist/index.node.cjs +26 -0
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.d.ts +49 -5
- package/dist/index.node.js +25 -1
- package/dist/index.node.js.map +1 -1
- package/dist/lib/__tests__/redisAtomicStore.test.d.ts +1 -0
- package/dist/lib/redisAtomicStore.cjs +201 -0
- package/dist/lib/redisAtomicStore.cjs.map +1 -0
- package/dist/lib/redisAtomicStore.d.ts +120 -0
- package/dist/lib/redisAtomicStore.js +177 -0
- package/dist/lib/redisAtomicStore.js.map +1 -0
- package/dist/server/relayerHandler.cjs +313 -75
- package/dist/server/relayerHandler.cjs.map +1 -1
- package/dist/server/relayerHandler.d.ts +35 -2
- package/dist/server/relayerHandler.js +313 -75
- package/dist/server/relayerHandler.js.map +1 -1
- package/dist/storage/index.cjs +3 -0
- package/dist/storage/index.cjs.map +1 -1
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.js +2 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/providers/dropbox.cjs +237 -0
- package/dist/storage/providers/dropbox.cjs.map +1 -0
- package/dist/storage/providers/dropbox.d.ts +39 -0
- package/dist/storage/providers/dropbox.js +215 -0
- package/dist/storage/providers/dropbox.js.map +1 -0
- package/dist/storage/providers/dropbox.test.d.ts +1 -0
- package/dist/tests/data-upload-owner-validation.test.d.ts +1 -0
- package/dist/types/atomicStore.cjs +31 -0
- package/dist/types/atomicStore.cjs.map +1 -0
- package/dist/types/atomicStore.d.ts +236 -0
- package/dist/types/atomicStore.js +7 -0
- package/dist/types/atomicStore.js.map +1 -0
- package/dist/types/config.cjs.map +1 -1
- package/dist/types/config.d.ts +32 -0
- package/dist/types/config.js.map +1 -1
- package/dist/types/controller-context.cjs.map +1 -1
- package/dist/types/controller-context.d.ts +4 -1
- package/dist/types/data.cjs.map +1 -1
- package/dist/types/data.d.ts +7 -4
- package/dist/types/generics.cjs.map +1 -1
- package/dist/types/generics.d.ts +1 -1
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.ts +6 -3
- package/dist/types/index.js.map +1 -1
- package/dist/types/operationStore.cjs +17 -0
- package/dist/types/operationStore.cjs.map +1 -0
- package/dist/types/operationStore.d.ts +171 -0
- package/dist/types/operationStore.js +1 -0
- package/dist/types/operationStore.js.map +1 -0
- package/dist/types/operations.cjs +3 -15
- package/dist/types/operations.cjs.map +1 -1
- package/dist/types/operations.d.ts +17 -42
- package/dist/types/operations.js +2 -13
- package/dist/types/operations.js.map +1 -1
- package/dist/types/options.cjs +17 -0
- package/dist/types/options.cjs.map +1 -0
- package/dist/types/options.d.ts +308 -0
- package/dist/types/options.js +1 -0
- package/dist/types/options.js.map +1 -0
- package/dist/types/permissions.cjs.map +1 -1
- package/dist/types/permissions.d.ts +4 -0
- package/dist/types/personal.cjs.map +1 -1
- package/dist/types/personal.d.ts +19 -0
- package/dist/types/relayer.cjs.map +1 -1
- package/dist/types/relayer.d.ts +53 -9
- package/dist/types/utils.cjs.map +1 -1
- package/dist/types/utils.d.ts +0 -49
- package/dist/utils/__tests__/chainQuery.test.d.ts +1 -0
- package/dist/utils/__tests__/subgraphConsistency.test.d.ts +4 -0
- package/dist/utils/__tests__/subgraphPagination.test.d.ts +4 -0
- package/dist/utils/chainQuery.cjs +107 -0
- package/dist/utils/chainQuery.cjs.map +1 -0
- package/dist/utils/chainQuery.d.ts +31 -0
- package/dist/utils/chainQuery.js +82 -0
- package/dist/utils/chainQuery.js.map +1 -0
- package/dist/utils/grantFiles.cjs +4 -1
- package/dist/utils/grantFiles.cjs.map +1 -1
- package/dist/utils/grantFiles.js +4 -1
- package/dist/utils/grantFiles.js.map +1 -1
- package/dist/utils/ipfs.cjs +2 -4
- package/dist/utils/ipfs.cjs.map +1 -1
- package/dist/utils/ipfs.d.ts +1 -1
- package/dist/utils/ipfs.js +2 -4
- package/dist/utils/ipfs.js.map +1 -1
- package/dist/utils/subgraphConsistency.cjs +184 -0
- package/dist/utils/subgraphConsistency.cjs.map +1 -0
- package/dist/utils/subgraphConsistency.d.ts +65 -0
- package/dist/utils/subgraphConsistency.js +155 -0
- package/dist/utils/subgraphConsistency.js.map +1 -0
- package/dist/utils/subgraphMetaCache.cjs +101 -0
- package/dist/utils/subgraphMetaCache.cjs.map +1 -0
- package/dist/utils/subgraphMetaCache.d.ts +56 -0
- package/dist/utils/subgraphMetaCache.js +76 -0
- package/dist/utils/subgraphMetaCache.js.map +1 -0
- package/dist/utils/subgraphPagination.cjs +104 -0
- package/dist/utils/subgraphPagination.cjs.map +1 -0
- package/dist/utils/subgraphPagination.d.ts +78 -0
- package/dist/utils/subgraphPagination.js +78 -0
- package/dist/utils/subgraphPagination.js.map +1 -0
- package/package.json +3 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getAddress } from "viem";
|
|
2
2
|
import { gasAwareMulticall } from "../utils/multicall";
|
|
3
|
+
import { PollingManager } from "../core/pollingManager";
|
|
3
4
|
import {
|
|
4
5
|
RelayerError,
|
|
5
6
|
UserRejectedRequestError,
|
|
@@ -57,10 +58,14 @@ class PermissionsController extends BaseController {
|
|
|
57
58
|
* await vana.permissions.revoke({ permissionId: result.permissionId });
|
|
58
59
|
* ```
|
|
59
60
|
*/
|
|
60
|
-
async grant(params) {
|
|
61
|
+
async grant(params, options) {
|
|
61
62
|
this.assertWallet();
|
|
62
63
|
const { typedData, signature } = await this.createAndSign(params);
|
|
63
|
-
const result = await this.submitSignedGrantWithEvents(
|
|
64
|
+
const result = await this.submitSignedGrantWithEvents(
|
|
65
|
+
typedData,
|
|
66
|
+
signature,
|
|
67
|
+
options
|
|
68
|
+
);
|
|
64
69
|
return result;
|
|
65
70
|
}
|
|
66
71
|
/**
|
|
@@ -88,10 +93,10 @@ class PermissionsController extends BaseController {
|
|
|
88
93
|
* console.log(`Permission ID: ${eventData.permissionId}`);
|
|
89
94
|
* ```
|
|
90
95
|
*/
|
|
91
|
-
async submitPermissionGrant(params) {
|
|
96
|
+
async submitPermissionGrant(params, options) {
|
|
92
97
|
this.assertWallet();
|
|
93
98
|
const { typedData, signature } = await this.createAndSign(params);
|
|
94
|
-
return await this.submitSignedGrant(typedData, signature);
|
|
99
|
+
return await this.submitSignedGrant(typedData, signature, options);
|
|
95
100
|
}
|
|
96
101
|
/**
|
|
97
102
|
* Prepares a permission grant with preview before signing.
|
|
@@ -118,7 +123,7 @@ class PermissionsController extends BaseController {
|
|
|
118
123
|
* const transactionHash = await confirm();
|
|
119
124
|
* ```
|
|
120
125
|
*/
|
|
121
|
-
async prepareGrant(params) {
|
|
126
|
+
async prepareGrant(params, options) {
|
|
122
127
|
this.assertWallet();
|
|
123
128
|
try {
|
|
124
129
|
const grantFile = createGrantFile(params);
|
|
@@ -126,7 +131,11 @@ class PermissionsController extends BaseController {
|
|
|
126
131
|
return {
|
|
127
132
|
preview: grantFile,
|
|
128
133
|
confirm: async () => {
|
|
129
|
-
return await this.confirmGrantInternalWithEvents(
|
|
134
|
+
return await this.confirmGrantInternalWithEvents(
|
|
135
|
+
params,
|
|
136
|
+
grantFile,
|
|
137
|
+
options
|
|
138
|
+
);
|
|
130
139
|
}
|
|
131
140
|
};
|
|
132
141
|
} catch (error) {
|
|
@@ -158,7 +167,7 @@ class PermissionsController extends BaseController {
|
|
|
158
167
|
* @throws {NetworkError} When IPFS upload fails
|
|
159
168
|
* @throws {SignatureError} When user rejects the signature
|
|
160
169
|
*/
|
|
161
|
-
async confirmGrantInternal(params, grantFile) {
|
|
170
|
+
async confirmGrantInternal(params, grantFile, options) {
|
|
162
171
|
try {
|
|
163
172
|
let { grantUrl } = params;
|
|
164
173
|
console.debug("\u{1F50D} Debug - Grant URL from params:", grantUrl);
|
|
@@ -183,7 +192,7 @@ class PermissionsController extends BaseController {
|
|
|
183
192
|
if (response.type === "error") {
|
|
184
193
|
throw new Error(response.error);
|
|
185
194
|
}
|
|
186
|
-
if (response.type === "direct" && typeof response.result === "object" && "url" in response.result) {
|
|
195
|
+
if (response.type === "direct" && typeof response.result === "object" && response.result !== null && "url" in response.result) {
|
|
187
196
|
grantUrl = response.result.url;
|
|
188
197
|
} else {
|
|
189
198
|
throw new Error("Invalid response from relayer for grant storage");
|
|
@@ -219,7 +228,7 @@ class PermissionsController extends BaseController {
|
|
|
219
228
|
nonce
|
|
220
229
|
});
|
|
221
230
|
const signature = await this.signTypedData(typedData);
|
|
222
|
-
return await this.submitSignedGrant(typedData, signature);
|
|
231
|
+
return await this.submitSignedGrant(typedData, signature, options);
|
|
223
232
|
} catch (error) {
|
|
224
233
|
if (error instanceof Error) {
|
|
225
234
|
if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof NetworkError || error instanceof NonceError) {
|
|
@@ -291,7 +300,7 @@ class PermissionsController extends BaseController {
|
|
|
291
300
|
if (response.type === "error") {
|
|
292
301
|
throw new Error(response.error);
|
|
293
302
|
}
|
|
294
|
-
if (response.type === "direct" && typeof response.result === "object" && "url" in response.result) {
|
|
303
|
+
if (response.type === "direct" && typeof response.result === "object" && response.result !== null && "url" in response.result) {
|
|
295
304
|
grantUrl = response.result.url;
|
|
296
305
|
} else {
|
|
297
306
|
throw new Error("Invalid response from relayer for grant storage");
|
|
@@ -364,7 +373,7 @@ class PermissionsController extends BaseController {
|
|
|
364
373
|
* );
|
|
365
374
|
* ```
|
|
366
375
|
*/
|
|
367
|
-
async submitSignedGrant(typedData, signature) {
|
|
376
|
+
async submitSignedGrant(typedData, signature, options) {
|
|
368
377
|
try {
|
|
369
378
|
console.debug(
|
|
370
379
|
"\u{1F50D} Debug - submitSignedGrant called with typed data:",
|
|
@@ -382,26 +391,41 @@ class PermissionsController extends BaseController {
|
|
|
382
391
|
signature,
|
|
383
392
|
expectedUserAddress: this.context.userAddress
|
|
384
393
|
});
|
|
385
|
-
|
|
386
|
-
if (response.type === "signed") {
|
|
387
|
-
hash = response.hash;
|
|
388
|
-
} else if (response.type === "error") {
|
|
394
|
+
if (response.type === "error") {
|
|
389
395
|
throw new Error(`Relayer error: ${response.error}`);
|
|
396
|
+
}
|
|
397
|
+
let finalHash;
|
|
398
|
+
if (response.type === "submitted") {
|
|
399
|
+
finalHash = response.hash;
|
|
400
|
+
} else if (response.type === "pending") {
|
|
401
|
+
const pollResult = await this.pollRelayerForConfirmation(
|
|
402
|
+
response.operationId,
|
|
403
|
+
options
|
|
404
|
+
);
|
|
405
|
+
finalHash = pollResult.hash;
|
|
406
|
+
} else if (response.type === "confirmed") {
|
|
407
|
+
finalHash = response.hash;
|
|
408
|
+
} else if (response.type === "signed") {
|
|
409
|
+
finalHash = response.hash;
|
|
390
410
|
} else {
|
|
391
411
|
throw new Error(
|
|
392
|
-
"Invalid response from relayer:
|
|
412
|
+
"Invalid response from relayer: unexpected response type"
|
|
393
413
|
);
|
|
394
414
|
}
|
|
395
415
|
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
396
416
|
const { tx } = await import("../utils/transactionHelpers");
|
|
397
417
|
return tx({
|
|
398
|
-
hash,
|
|
418
|
+
hash: finalHash,
|
|
399
419
|
from: typeof account === "string" ? account : account.address,
|
|
400
420
|
contract: "DataPortabilityPermissions",
|
|
401
421
|
fn: "addPermission"
|
|
402
422
|
});
|
|
403
423
|
} else {
|
|
404
|
-
return await this.submitDirectTransaction(
|
|
424
|
+
return await this.submitDirectTransaction(
|
|
425
|
+
typedData,
|
|
426
|
+
signature,
|
|
427
|
+
options
|
|
428
|
+
);
|
|
405
429
|
}
|
|
406
430
|
} catch (error) {
|
|
407
431
|
if (error instanceof RelayerError || error instanceof NetworkError || error instanceof UserRejectedRequestError || error instanceof SignatureError || error instanceof NonceError) {
|
|
@@ -434,7 +458,7 @@ class PermissionsController extends BaseController {
|
|
|
434
458
|
* const result = await txHandle.waitForEvents();
|
|
435
459
|
* ```
|
|
436
460
|
*/
|
|
437
|
-
async submitSignedTrustServer(typedData, signature) {
|
|
461
|
+
async submitSignedTrustServer(typedData, signature, options) {
|
|
438
462
|
try {
|
|
439
463
|
const trustServerInput = {
|
|
440
464
|
nonce: BigInt(typedData.message.nonce),
|
|
@@ -442,7 +466,8 @@ class PermissionsController extends BaseController {
|
|
|
442
466
|
};
|
|
443
467
|
const hash = await this.submitTrustServerTransaction(
|
|
444
468
|
trustServerInput,
|
|
445
|
-
signature
|
|
469
|
+
signature,
|
|
470
|
+
options
|
|
446
471
|
);
|
|
447
472
|
const account = this.context.userAddress;
|
|
448
473
|
const { tx } = await import("../utils/transactionHelpers");
|
|
@@ -497,7 +522,7 @@ class PermissionsController extends BaseController {
|
|
|
497
522
|
* const result = await txHandle.waitForEvents();
|
|
498
523
|
* ```
|
|
499
524
|
*/
|
|
500
|
-
async submitSignedAddAndTrustServer(typedData, signature) {
|
|
525
|
+
async submitSignedAddAndTrustServer(typedData, signature, options) {
|
|
501
526
|
try {
|
|
502
527
|
const addAndTrustServerInput = {
|
|
503
528
|
nonce: BigInt(typedData.message.nonce),
|
|
@@ -507,7 +532,8 @@ class PermissionsController extends BaseController {
|
|
|
507
532
|
};
|
|
508
533
|
const hash = await this.submitAddAndTrustServerTransaction(
|
|
509
534
|
addAndTrustServerInput,
|
|
510
|
-
signature
|
|
535
|
+
signature,
|
|
536
|
+
options
|
|
511
537
|
);
|
|
512
538
|
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
513
539
|
const { tx } = await import("../utils/transactionHelpers");
|
|
@@ -535,8 +561,12 @@ class PermissionsController extends BaseController {
|
|
|
535
561
|
* @param signature - The user's signature authorizing the transaction
|
|
536
562
|
* @returns Promise resolving to PermissionGrantResult with parsed events
|
|
537
563
|
*/
|
|
538
|
-
async submitSignedGrantWithEvents(typedData, signature) {
|
|
539
|
-
const txResult = await this.submitSignedGrant(
|
|
564
|
+
async submitSignedGrantWithEvents(typedData, signature, options) {
|
|
565
|
+
const txResult = await this.submitSignedGrant(
|
|
566
|
+
typedData,
|
|
567
|
+
signature,
|
|
568
|
+
options
|
|
569
|
+
);
|
|
540
570
|
if (!this.context.waitForTransactionEvents) {
|
|
541
571
|
throw new BlockchainError("waitForTransactionEvents not configured");
|
|
542
572
|
}
|
|
@@ -568,8 +598,12 @@ class PermissionsController extends BaseController {
|
|
|
568
598
|
* @param grantFile - The pre-created grant file object
|
|
569
599
|
* @returns Promise resolving to PermissionGrantResult with parsed events
|
|
570
600
|
*/
|
|
571
|
-
async confirmGrantInternalWithEvents(params, grantFile) {
|
|
572
|
-
const txResult = await this.confirmGrantInternal(
|
|
601
|
+
async confirmGrantInternalWithEvents(params, grantFile, options) {
|
|
602
|
+
const txResult = await this.confirmGrantInternal(
|
|
603
|
+
params,
|
|
604
|
+
grantFile,
|
|
605
|
+
options
|
|
606
|
+
);
|
|
573
607
|
if (!this.context.waitForTransactionEvents) {
|
|
574
608
|
throw new BlockchainError("waitForTransactionEvents not configured");
|
|
575
609
|
}
|
|
@@ -593,6 +627,27 @@ class PermissionsController extends BaseController {
|
|
|
593
627
|
fileIds: event.fileIds
|
|
594
628
|
};
|
|
595
629
|
}
|
|
630
|
+
/**
|
|
631
|
+
* Polls the relayer for confirmation of a pending operation.
|
|
632
|
+
*
|
|
633
|
+
* @param operationId - The operation ID to poll
|
|
634
|
+
* @param options - Polling configuration including status updates and cancellation
|
|
635
|
+
* @returns Promise resolving to the confirmed hash and receipt
|
|
636
|
+
* @throws {TransactionPendingError} When the operation times out
|
|
637
|
+
* @throws {Error} When the operation fails or is cancelled
|
|
638
|
+
* @internal
|
|
639
|
+
*/
|
|
640
|
+
async pollRelayerForConfirmation(operationId, options) {
|
|
641
|
+
if (!this.context.relayer) {
|
|
642
|
+
throw new Error("Relayer not configured for polling");
|
|
643
|
+
}
|
|
644
|
+
const pollingManager = new PollingManager(this.context.relayer);
|
|
645
|
+
return await pollingManager.startPolling(operationId, {
|
|
646
|
+
signal: options?.signal,
|
|
647
|
+
onStatusUpdate: options?.onStatusUpdate,
|
|
648
|
+
...options?.pollingOptions
|
|
649
|
+
});
|
|
650
|
+
}
|
|
596
651
|
/**
|
|
597
652
|
* Submits an already-signed permission revoke transaction to the blockchain.
|
|
598
653
|
*
|
|
@@ -614,7 +669,7 @@ class PermissionsController extends BaseController {
|
|
|
614
669
|
* const result = await txHandle.waitForEvents();
|
|
615
670
|
* ```
|
|
616
671
|
*/
|
|
617
|
-
async submitSignedRevoke(typedData, signature) {
|
|
672
|
+
async submitSignedRevoke(typedData, signature, options) {
|
|
618
673
|
try {
|
|
619
674
|
let hash;
|
|
620
675
|
if (this.context.relayer) {
|
|
@@ -625,19 +680,31 @@ class PermissionsController extends BaseController {
|
|
|
625
680
|
signature,
|
|
626
681
|
expectedUserAddress: this.context.userAddress
|
|
627
682
|
});
|
|
628
|
-
if (response.type === "
|
|
629
|
-
hash = response.hash;
|
|
630
|
-
} else if (response.type === "error") {
|
|
683
|
+
if (response.type === "error") {
|
|
631
684
|
throw new Error(`Relayer error: ${response.error}`);
|
|
685
|
+
}
|
|
686
|
+
if (response.type === "submitted") {
|
|
687
|
+
hash = response.hash;
|
|
688
|
+
} else if (response.type === "pending") {
|
|
689
|
+
const pollResult = await this.pollRelayerForConfirmation(
|
|
690
|
+
response.operationId,
|
|
691
|
+
options
|
|
692
|
+
);
|
|
693
|
+
hash = pollResult.hash;
|
|
694
|
+
} else if (response.type === "confirmed") {
|
|
695
|
+
hash = response.hash;
|
|
696
|
+
} else if (response.type === "signed") {
|
|
697
|
+
hash = response.hash;
|
|
632
698
|
} else {
|
|
633
699
|
throw new Error(
|
|
634
|
-
"Invalid response from relayer:
|
|
700
|
+
"Invalid response from relayer: unexpected response type"
|
|
635
701
|
);
|
|
636
702
|
}
|
|
637
703
|
} else {
|
|
638
704
|
hash = await this.submitDirectRevokeTransaction(
|
|
639
705
|
typedData,
|
|
640
|
-
signature
|
|
706
|
+
signature,
|
|
707
|
+
options
|
|
641
708
|
);
|
|
642
709
|
}
|
|
643
710
|
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
@@ -679,7 +746,7 @@ class PermissionsController extends BaseController {
|
|
|
679
746
|
* const result = await txHandle.waitForEvents();
|
|
680
747
|
* ```
|
|
681
748
|
*/
|
|
682
|
-
async submitSignedUntrustServer(typedData, signature) {
|
|
749
|
+
async submitSignedUntrustServer(typedData, signature, options) {
|
|
683
750
|
try {
|
|
684
751
|
let hash;
|
|
685
752
|
if (this.context.relayer) {
|
|
@@ -690,7 +757,9 @@ class PermissionsController extends BaseController {
|
|
|
690
757
|
signature,
|
|
691
758
|
expectedUserAddress: this.context.userAddress
|
|
692
759
|
});
|
|
693
|
-
if (response.type === "
|
|
760
|
+
if (response.type === "submitted") {
|
|
761
|
+
hash = response.hash;
|
|
762
|
+
} else if (response.type === "signed") {
|
|
694
763
|
hash = response.hash;
|
|
695
764
|
} else if (response.type === "error") {
|
|
696
765
|
throw new Error(`Relayer error: ${response.error}`);
|
|
@@ -702,7 +771,8 @@ class PermissionsController extends BaseController {
|
|
|
702
771
|
} else {
|
|
703
772
|
hash = await this.submitSignedUntrustTransaction(
|
|
704
773
|
typedData,
|
|
705
|
-
signature
|
|
774
|
+
signature,
|
|
775
|
+
options
|
|
706
776
|
);
|
|
707
777
|
}
|
|
708
778
|
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
@@ -735,7 +805,7 @@ class PermissionsController extends BaseController {
|
|
|
735
805
|
* @returns Promise resolving to the transaction hash
|
|
736
806
|
* @throws {BlockchainError} When contract submission fails
|
|
737
807
|
*/
|
|
738
|
-
async submitDirectTransaction(typedData, signature) {
|
|
808
|
+
async submitDirectTransaction(typedData, signature, options) {
|
|
739
809
|
this.assertWallet();
|
|
740
810
|
const chainId = await this.context.publicClient.getChainId();
|
|
741
811
|
const DataPortabilityPermissionsAddress = getContractAddress(
|
|
@@ -767,7 +837,8 @@ class PermissionsController extends BaseController {
|
|
|
767
837
|
functionName: "addPermission",
|
|
768
838
|
args: [permissionInput, formattedSignature],
|
|
769
839
|
account,
|
|
770
|
-
chain: this.context.walletClient?.chain ?? null
|
|
840
|
+
chain: this.context.walletClient?.chain ?? null,
|
|
841
|
+
...this.spreadTransactionOptions(options)
|
|
771
842
|
});
|
|
772
843
|
const { tx } = await import("../utils/transactionHelpers");
|
|
773
844
|
return tx({
|
|
@@ -866,7 +937,7 @@ class PermissionsController extends BaseController {
|
|
|
866
937
|
args: [params.permissionId],
|
|
867
938
|
account,
|
|
868
939
|
chain: this.context.walletClient?.chain ?? null,
|
|
869
|
-
...options?.
|
|
940
|
+
...options?.gas && { gas: options.gas },
|
|
870
941
|
...options?.nonce && { nonce: options.nonce },
|
|
871
942
|
// Use EIP-1559 if available, otherwise fall back to legacy gasPrice
|
|
872
943
|
...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
|
|
@@ -923,7 +994,7 @@ class PermissionsController extends BaseController {
|
|
|
923
994
|
* console.log(`Permission ${result.permissionId} revoked`);
|
|
924
995
|
* ```
|
|
925
996
|
*/
|
|
926
|
-
async submitRevokeWithSignature(params) {
|
|
997
|
+
async submitRevokeWithSignature(params, options) {
|
|
927
998
|
this.assertWallet();
|
|
928
999
|
try {
|
|
929
1000
|
if (!this.context.walletClient?.chain?.id) {
|
|
@@ -955,7 +1026,9 @@ class PermissionsController extends BaseController {
|
|
|
955
1026
|
signature,
|
|
956
1027
|
expectedUserAddress: this.context.userAddress
|
|
957
1028
|
});
|
|
958
|
-
if (response.type === "
|
|
1029
|
+
if (response.type === "submitted") {
|
|
1030
|
+
hash = response.hash;
|
|
1031
|
+
} else if (response.type === "signed") {
|
|
959
1032
|
hash = response.hash;
|
|
960
1033
|
} else if (response.type === "error") {
|
|
961
1034
|
throw new Error(`Relayer error: ${response.error}`);
|
|
@@ -967,7 +1040,8 @@ class PermissionsController extends BaseController {
|
|
|
967
1040
|
} else {
|
|
968
1041
|
hash = await this.submitDirectRevokeTransaction(
|
|
969
1042
|
typedData,
|
|
970
|
-
signature
|
|
1043
|
+
signature,
|
|
1044
|
+
options
|
|
971
1045
|
);
|
|
972
1046
|
}
|
|
973
1047
|
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
@@ -1293,7 +1367,9 @@ class PermissionsController extends BaseController {
|
|
|
1293
1367
|
* ```
|
|
1294
1368
|
*/
|
|
1295
1369
|
async getUserPermissionGrantsOnChain(options = {}) {
|
|
1296
|
-
const { limit = 50, subgraphUrl } = options;
|
|
1370
|
+
const { limit = 50, fetchAll = false, subgraphUrl } = options;
|
|
1371
|
+
const pageSize = fetchAll ? 100 : limit;
|
|
1372
|
+
const maxResults = fetchAll ? 1e4 : limit;
|
|
1297
1373
|
try {
|
|
1298
1374
|
const userAddress = this.context.userAddress;
|
|
1299
1375
|
const graphqlEndpoint = subgraphUrl ?? this.context.subgraphUrl;
|
|
@@ -1303,10 +1379,10 @@ class PermissionsController extends BaseController {
|
|
|
1303
1379
|
);
|
|
1304
1380
|
}
|
|
1305
1381
|
const query = `
|
|
1306
|
-
query GetUserPermissions($userId: ID!) {
|
|
1382
|
+
query GetUserPermissions($userId: ID!, $first: Int!, $skip: Int!) {
|
|
1307
1383
|
user(id: $userId) {
|
|
1308
1384
|
id
|
|
1309
|
-
permissions {
|
|
1385
|
+
permissions(first: $first, skip: $skip, orderBy: addedAtBlock, orderDirection: desc) {
|
|
1310
1386
|
id
|
|
1311
1387
|
grant
|
|
1312
1388
|
nonce
|
|
@@ -1324,34 +1400,82 @@ class PermissionsController extends BaseController {
|
|
|
1324
1400
|
}
|
|
1325
1401
|
}
|
|
1326
1402
|
`;
|
|
1327
|
-
const
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1403
|
+
const allPermissions = [];
|
|
1404
|
+
let currentOffset = 0;
|
|
1405
|
+
if (!fetchAll) {
|
|
1406
|
+
const response = await fetch(graphqlEndpoint, {
|
|
1407
|
+
method: "POST",
|
|
1408
|
+
headers: {
|
|
1409
|
+
"Content-Type": "application/json"
|
|
1410
|
+
},
|
|
1411
|
+
body: JSON.stringify({
|
|
1412
|
+
query,
|
|
1413
|
+
variables: {
|
|
1414
|
+
userId: userAddress.toLowerCase(),
|
|
1415
|
+
first: limit,
|
|
1416
|
+
skip: 0
|
|
1417
|
+
}
|
|
1418
|
+
})
|
|
1419
|
+
});
|
|
1420
|
+
if (!response.ok) {
|
|
1421
|
+
throw new BlockchainError(
|
|
1422
|
+
`Subgraph request failed: ${response.status} ${response.statusText}`
|
|
1423
|
+
);
|
|
1424
|
+
}
|
|
1425
|
+
const result = await response.json();
|
|
1426
|
+
if (result.errors) {
|
|
1427
|
+
throw new BlockchainError(
|
|
1428
|
+
`Subgraph errors: ${result.errors.map((e) => e.message).join(", ")}`
|
|
1429
|
+
);
|
|
1430
|
+
}
|
|
1431
|
+
const userData = result.data?.user;
|
|
1432
|
+
if (!userData?.permissions?.length) {
|
|
1433
|
+
return [];
|
|
1434
|
+
}
|
|
1435
|
+
allPermissions.push(...userData.permissions);
|
|
1436
|
+
} else {
|
|
1437
|
+
while (allPermissions.length < maxResults) {
|
|
1438
|
+
const currentLimit = Math.min(
|
|
1439
|
+
pageSize,
|
|
1440
|
+
maxResults - allPermissions.length
|
|
1441
|
+
);
|
|
1442
|
+
const response = await fetch(graphqlEndpoint, {
|
|
1443
|
+
method: "POST",
|
|
1444
|
+
headers: {
|
|
1445
|
+
"Content-Type": "application/json"
|
|
1446
|
+
},
|
|
1447
|
+
body: JSON.stringify({
|
|
1448
|
+
query,
|
|
1449
|
+
variables: {
|
|
1450
|
+
userId: userAddress.toLowerCase(),
|
|
1451
|
+
first: currentLimit,
|
|
1452
|
+
skip: currentOffset
|
|
1453
|
+
}
|
|
1454
|
+
})
|
|
1455
|
+
});
|
|
1456
|
+
if (!response.ok) {
|
|
1457
|
+
throw new BlockchainError(
|
|
1458
|
+
`Subgraph request failed: ${response.status} ${response.statusText}`
|
|
1459
|
+
);
|
|
1336
1460
|
}
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1461
|
+
const result = await response.json();
|
|
1462
|
+
if (result.errors) {
|
|
1463
|
+
throw new BlockchainError(
|
|
1464
|
+
`Subgraph errors: ${result.errors.map((e) => e.message).join(", ")}`
|
|
1465
|
+
);
|
|
1466
|
+
}
|
|
1467
|
+
const userData = result.data?.user;
|
|
1468
|
+
if (!userData?.permissions?.length) {
|
|
1469
|
+
break;
|
|
1470
|
+
}
|
|
1471
|
+
allPermissions.push(...userData.permissions);
|
|
1472
|
+
if (userData.permissions.length < currentLimit) {
|
|
1473
|
+
break;
|
|
1474
|
+
}
|
|
1475
|
+
currentOffset += userData.permissions.length;
|
|
1476
|
+
}
|
|
1353
1477
|
}
|
|
1354
|
-
const onChainGrants =
|
|
1478
|
+
const onChainGrants = allPermissions.map(
|
|
1355
1479
|
(permission) => ({
|
|
1356
1480
|
id: BigInt(permission.id),
|
|
1357
1481
|
grantUrl: permission.grant,
|
|
@@ -1532,7 +1656,7 @@ class PermissionsController extends BaseController {
|
|
|
1532
1656
|
* @param params - Parameters for adding and trusting the server
|
|
1533
1657
|
* @returns Promise resolving to TransactionResult with ServerTrustResult event data
|
|
1534
1658
|
*/
|
|
1535
|
-
async submitAddAndTrustServerWithSignature(params) {
|
|
1659
|
+
async submitAddAndTrustServerWithSignature(params, options) {
|
|
1536
1660
|
this.assertWallet();
|
|
1537
1661
|
try {
|
|
1538
1662
|
const nonce = await this.getServersUserNonce();
|
|
@@ -1568,7 +1692,9 @@ class PermissionsController extends BaseController {
|
|
|
1568
1692
|
if (response.type === "error") {
|
|
1569
1693
|
throw new RelayerError(response.error);
|
|
1570
1694
|
}
|
|
1571
|
-
if (response.type === "
|
|
1695
|
+
if (response.type === "submitted") {
|
|
1696
|
+
hash = response.hash;
|
|
1697
|
+
} else if (response.type === "signed") {
|
|
1572
1698
|
hash = response.hash;
|
|
1573
1699
|
} else {
|
|
1574
1700
|
throw new Error("Unexpected response type from relayer");
|
|
@@ -1576,7 +1702,8 @@ class PermissionsController extends BaseController {
|
|
|
1576
1702
|
} else {
|
|
1577
1703
|
hash = await this.submitAddAndTrustServerTransaction(
|
|
1578
1704
|
addAndTrustServerInput,
|
|
1579
|
-
signature
|
|
1705
|
+
signature,
|
|
1706
|
+
options
|
|
1580
1707
|
);
|
|
1581
1708
|
}
|
|
1582
1709
|
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
@@ -1615,7 +1742,7 @@ class PermissionsController extends BaseController {
|
|
|
1615
1742
|
* @throws {ServerUrlMismatchError} When server URL doesn't match existing registration
|
|
1616
1743
|
* @throws {BlockchainError} When trust operation fails for any other reason
|
|
1617
1744
|
*/
|
|
1618
|
-
async submitTrustServerWithSignature(params) {
|
|
1745
|
+
async submitTrustServerWithSignature(params, options) {
|
|
1619
1746
|
this.assertWallet();
|
|
1620
1747
|
try {
|
|
1621
1748
|
const nonce = await this.getServersUserNonce();
|
|
@@ -1637,7 +1764,9 @@ class PermissionsController extends BaseController {
|
|
|
1637
1764
|
if (response.type === "error") {
|
|
1638
1765
|
throw new RelayerError(response.error);
|
|
1639
1766
|
}
|
|
1640
|
-
if (response.type === "
|
|
1767
|
+
if (response.type === "submitted") {
|
|
1768
|
+
hash = response.hash;
|
|
1769
|
+
} else if (response.type === "signed") {
|
|
1641
1770
|
hash = response.hash;
|
|
1642
1771
|
} else {
|
|
1643
1772
|
throw new Error("Unexpected response type from relayer");
|
|
@@ -1645,7 +1774,8 @@ class PermissionsController extends BaseController {
|
|
|
1645
1774
|
} else {
|
|
1646
1775
|
hash = await this.submitTrustServerTransaction(
|
|
1647
1776
|
trustServerInput,
|
|
1648
|
-
signature
|
|
1777
|
+
signature,
|
|
1778
|
+
options
|
|
1649
1779
|
);
|
|
1650
1780
|
}
|
|
1651
1781
|
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
@@ -1703,7 +1833,7 @@ class PermissionsController extends BaseController {
|
|
|
1703
1833
|
args: [BigInt(params.serverId)],
|
|
1704
1834
|
account,
|
|
1705
1835
|
chain: this.context.walletClient?.chain ?? null,
|
|
1706
|
-
...options?.
|
|
1836
|
+
...options?.gas && { gas: options.gas },
|
|
1707
1837
|
...options?.nonce && { nonce: options.nonce },
|
|
1708
1838
|
// Use EIP-1559 if available, otherwise fall back to legacy gasPrice
|
|
1709
1839
|
...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
|
|
@@ -1807,7 +1937,9 @@ class PermissionsController extends BaseController {
|
|
|
1807
1937
|
if (response.type === "error") {
|
|
1808
1938
|
throw new RelayerError(response.error);
|
|
1809
1939
|
}
|
|
1810
|
-
if (response.type === "
|
|
1940
|
+
if (response.type === "submitted") {
|
|
1941
|
+
hash = response.hash;
|
|
1942
|
+
} else if (response.type === "signed") {
|
|
1811
1943
|
hash = response.hash;
|
|
1812
1944
|
} else {
|
|
1813
1945
|
throw new Error("Unexpected response type from relayer");
|
|
@@ -2253,7 +2385,7 @@ class PermissionsController extends BaseController {
|
|
|
2253
2385
|
* @param signature - The cryptographic signature for the transaction
|
|
2254
2386
|
* @returns Promise resolving to the transaction hash
|
|
2255
2387
|
*/
|
|
2256
|
-
async submitAddAndTrustServerTransaction(addAndTrustServerInput, signature) {
|
|
2388
|
+
async submitAddAndTrustServerTransaction(addAndTrustServerInput, signature, options) {
|
|
2257
2389
|
this.assertWallet();
|
|
2258
2390
|
const chainId = await this.context.walletClient.getChainId();
|
|
2259
2391
|
const DataPortabilityServersAddress = getContractAddress(
|
|
@@ -2287,7 +2419,16 @@ class PermissionsController extends BaseController {
|
|
|
2287
2419
|
formattedSignature
|
|
2288
2420
|
],
|
|
2289
2421
|
account: this.context.walletClient?.account ?? this.context.userAddress,
|
|
2290
|
-
chain: this.context.walletClient?.chain ?? null
|
|
2422
|
+
chain: this.context.walletClient?.chain ?? null,
|
|
2423
|
+
...options && {
|
|
2424
|
+
gas: options.gas,
|
|
2425
|
+
nonce: options.nonce,
|
|
2426
|
+
// Use EIP-1559 gas pricing if available, otherwise legacy
|
|
2427
|
+
...options.maxFeePerGas || options.maxPriorityFeePerGas ? {
|
|
2428
|
+
maxFeePerGas: options.maxFeePerGas,
|
|
2429
|
+
maxPriorityFeePerGas: options.maxPriorityFeePerGas
|
|
2430
|
+
} : options.gasPrice ? { gasPrice: options.gasPrice } : {}
|
|
2431
|
+
}
|
|
2291
2432
|
});
|
|
2292
2433
|
return txHash;
|
|
2293
2434
|
}
|
|
@@ -2298,7 +2439,7 @@ class PermissionsController extends BaseController {
|
|
|
2298
2439
|
* @param signature - The cryptographic signature for the transaction
|
|
2299
2440
|
* @returns Promise resolving to the transaction hash
|
|
2300
2441
|
*/
|
|
2301
|
-
async submitTrustServerTransaction(trustServerInput, signature) {
|
|
2442
|
+
async submitTrustServerTransaction(trustServerInput, signature, options) {
|
|
2302
2443
|
this.assertWallet();
|
|
2303
2444
|
const chainId = await this.context.walletClient.getChainId();
|
|
2304
2445
|
const DataPortabilityServersAddress = getContractAddress(
|
|
@@ -2319,7 +2460,8 @@ class PermissionsController extends BaseController {
|
|
|
2319
2460
|
formattedSignature
|
|
2320
2461
|
],
|
|
2321
2462
|
account: this.context.walletClient?.account ?? this.context.userAddress,
|
|
2322
|
-
chain: this.context.walletClient?.chain ?? null
|
|
2463
|
+
chain: this.context.walletClient?.chain ?? null,
|
|
2464
|
+
...this.spreadTransactionOptions(options)
|
|
2323
2465
|
});
|
|
2324
2466
|
return txHash;
|
|
2325
2467
|
}
|
|
@@ -2330,7 +2472,7 @@ class PermissionsController extends BaseController {
|
|
|
2330
2472
|
* @param signature - The cryptographic signature authorizing the revoke
|
|
2331
2473
|
* @returns Promise resolving to the transaction hash
|
|
2332
2474
|
*/
|
|
2333
|
-
async submitDirectRevokeTransaction(typedData, signature) {
|
|
2475
|
+
async submitDirectRevokeTransaction(typedData, signature, options) {
|
|
2334
2476
|
this.assertWallet();
|
|
2335
2477
|
const chainId = await this.context.walletClient.getChainId();
|
|
2336
2478
|
const DataPortabilityPermissionsAddress = getContractAddress(
|
|
@@ -2345,7 +2487,16 @@ class PermissionsController extends BaseController {
|
|
|
2345
2487
|
functionName: "revokePermissionWithSignature",
|
|
2346
2488
|
args: [typedData.message, formattedSignature],
|
|
2347
2489
|
account: this.context.walletClient?.account ?? this.context.userAddress,
|
|
2348
|
-
chain: this.context.walletClient?.chain ?? null
|
|
2490
|
+
chain: this.context.walletClient?.chain ?? null,
|
|
2491
|
+
...options && {
|
|
2492
|
+
gas: options.gas,
|
|
2493
|
+
nonce: options.nonce,
|
|
2494
|
+
// Use EIP-1559 gas pricing if available, otherwise legacy
|
|
2495
|
+
...options.maxFeePerGas || options.maxPriorityFeePerGas ? {
|
|
2496
|
+
maxFeePerGas: options.maxFeePerGas,
|
|
2497
|
+
maxPriorityFeePerGas: options.maxPriorityFeePerGas
|
|
2498
|
+
} : options.gasPrice ? { gasPrice: options.gasPrice } : {}
|
|
2499
|
+
}
|
|
2349
2500
|
});
|
|
2350
2501
|
return txHash;
|
|
2351
2502
|
}
|
|
@@ -2356,7 +2507,7 @@ class PermissionsController extends BaseController {
|
|
|
2356
2507
|
* @param signature - The cryptographic signature authorizing the untrust
|
|
2357
2508
|
* @returns Promise resolving to the transaction hash
|
|
2358
2509
|
*/
|
|
2359
|
-
async submitSignedUntrustTransaction(typedData, signature) {
|
|
2510
|
+
async submitSignedUntrustTransaction(typedData, signature, options) {
|
|
2360
2511
|
this.assertWallet();
|
|
2361
2512
|
const chainId = await this.context.walletClient.getChainId();
|
|
2362
2513
|
const DataPortabilityServersAddress = getContractAddress(
|
|
@@ -2375,7 +2526,16 @@ class PermissionsController extends BaseController {
|
|
|
2375
2526
|
functionName: "untrustServerWithSignature",
|
|
2376
2527
|
args: [contractMessage, formattedSignature],
|
|
2377
2528
|
account: this.context.walletClient?.account ?? this.context.userAddress,
|
|
2378
|
-
chain: this.context.walletClient?.chain ?? null
|
|
2529
|
+
chain: this.context.walletClient?.chain ?? null,
|
|
2530
|
+
...options && {
|
|
2531
|
+
gas: options.gas,
|
|
2532
|
+
nonce: options.nonce,
|
|
2533
|
+
// Use EIP-1559 gas pricing if available, otherwise legacy
|
|
2534
|
+
...options.maxFeePerGas || options.maxPriorityFeePerGas ? {
|
|
2535
|
+
maxFeePerGas: options.maxFeePerGas,
|
|
2536
|
+
maxPriorityFeePerGas: options.maxPriorityFeePerGas
|
|
2537
|
+
} : options.gasPrice ? { gasPrice: options.gasPrice } : {}
|
|
2538
|
+
}
|
|
2379
2539
|
});
|
|
2380
2540
|
return txHash;
|
|
2381
2541
|
}
|
|
@@ -2388,6 +2548,9 @@ class PermissionsController extends BaseController {
|
|
|
2388
2548
|
* A grantee is an entity (like an application) that can receive data permissions
|
|
2389
2549
|
* from users. Once registered, users can grant the grantee access to their data.
|
|
2390
2550
|
*
|
|
2551
|
+
* This method supports gasless transactions via relayer when configured.
|
|
2552
|
+
* If no relayer is available, it falls back to direct wallet transactions.
|
|
2553
|
+
*
|
|
2391
2554
|
* @param params - Parameters for registering the grantee
|
|
2392
2555
|
* @param params.owner - The Ethereum address that will own this grantee registration
|
|
2393
2556
|
* @param params.granteeAddress - The Ethereum address of the grantee (application)
|
|
@@ -2396,7 +2559,7 @@ class PermissionsController extends BaseController {
|
|
|
2396
2559
|
* @returns Promise resolving to the transaction hash
|
|
2397
2560
|
* @throws {BlockchainError} When the grantee registration transaction fails
|
|
2398
2561
|
* @throws {UserRejectedRequestError} When user rejects the transaction
|
|
2399
|
-
* @throws {
|
|
2562
|
+
* @throws {RelayerError} When gasless transaction submission fails
|
|
2400
2563
|
*
|
|
2401
2564
|
* @example
|
|
2402
2565
|
* ```typescript
|
|
@@ -2409,44 +2572,87 @@ class PermissionsController extends BaseController {
|
|
|
2409
2572
|
* ```
|
|
2410
2573
|
*/
|
|
2411
2574
|
async submitRegisterGrantee(params, options) {
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
account,
|
|
2428
|
-
chain: this.context.walletClient?.chain ?? null,
|
|
2429
|
-
...options?.gasLimit && { gas: options.gasLimit },
|
|
2430
|
-
...options?.nonce && { nonce: options.nonce },
|
|
2431
|
-
// Use EIP-1559 if available, otherwise fall back to legacy gasPrice
|
|
2432
|
-
...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
|
|
2433
|
-
...options.maxFeePerGas && { maxFeePerGas: options.maxFeePerGas },
|
|
2434
|
-
...options.maxPriorityFeePerGas && {
|
|
2435
|
-
maxPriorityFeePerGas: options.maxPriorityFeePerGas
|
|
2575
|
+
try {
|
|
2576
|
+
let hash;
|
|
2577
|
+
if (this.context.relayer) {
|
|
2578
|
+
const request = {
|
|
2579
|
+
type: "direct",
|
|
2580
|
+
operation: "submitRegisterGrantee",
|
|
2581
|
+
params: {
|
|
2582
|
+
owner: params.owner,
|
|
2583
|
+
granteeAddress: params.granteeAddress,
|
|
2584
|
+
publicKey: params.publicKey
|
|
2585
|
+
}
|
|
2586
|
+
};
|
|
2587
|
+
const response = await this.context.relayer(request);
|
|
2588
|
+
if (response.type === "error") {
|
|
2589
|
+
throw new RelayerError(response.error);
|
|
2436
2590
|
}
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2591
|
+
if (response.type === "submitted") {
|
|
2592
|
+
hash = response.hash;
|
|
2593
|
+
} else if (response.type === "direct") {
|
|
2594
|
+
const result = response.result;
|
|
2595
|
+
hash = result.transactionHash;
|
|
2596
|
+
} else {
|
|
2597
|
+
throw new Error("Unexpected response type from relayer");
|
|
2598
|
+
}
|
|
2599
|
+
} else {
|
|
2600
|
+
this.assertWallet();
|
|
2601
|
+
const chainId = await this.context.walletClient.getChainId();
|
|
2602
|
+
const DataPortabilityGranteesAddress = getContractAddress(
|
|
2603
|
+
chainId,
|
|
2604
|
+
"DataPortabilityGrantees"
|
|
2605
|
+
);
|
|
2606
|
+
const DataPortabilityGranteesAbi = getAbi("DataPortabilityGrantees");
|
|
2607
|
+
const ownerAddress = getAddress(params.owner);
|
|
2608
|
+
const granteeAddress = getAddress(params.granteeAddress);
|
|
2609
|
+
const account2 = this.context.walletClient?.account ?? this.context.userAddress;
|
|
2610
|
+
hash = await this.context.walletClient.writeContract({
|
|
2611
|
+
address: DataPortabilityGranteesAddress,
|
|
2612
|
+
abi: DataPortabilityGranteesAbi,
|
|
2613
|
+
functionName: "registerGrantee",
|
|
2614
|
+
args: [ownerAddress, granteeAddress, params.publicKey],
|
|
2615
|
+
account: account2,
|
|
2616
|
+
chain: this.context.walletClient?.chain ?? null,
|
|
2617
|
+
...this.spreadTransactionOptions(options)
|
|
2618
|
+
});
|
|
2619
|
+
}
|
|
2620
|
+
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
2621
|
+
const { tx } = await import("../utils/transactionHelpers");
|
|
2622
|
+
return tx({
|
|
2623
|
+
hash,
|
|
2624
|
+
from: typeof account === "string" ? account : account.address,
|
|
2625
|
+
contract: "DataPortabilityGrantees",
|
|
2626
|
+
fn: "registerGrantee"
|
|
2627
|
+
});
|
|
2628
|
+
} catch (error) {
|
|
2629
|
+
if (error instanceof Error) {
|
|
2630
|
+
if (error instanceof RelayerError || error instanceof UserRejectedRequestError || error instanceof SerializationError || error instanceof SignatureError || error instanceof BlockchainError) {
|
|
2631
|
+
throw error;
|
|
2632
|
+
}
|
|
2633
|
+
if (error.name === "ContractFunctionExecutionError") {
|
|
2634
|
+
throw new BlockchainError(
|
|
2635
|
+
`Grantee registration failed: ${error.message}`,
|
|
2636
|
+
error
|
|
2637
|
+
);
|
|
2638
|
+
}
|
|
2639
|
+
if (error.name === "UserRejectedRequestError") {
|
|
2640
|
+
throw new UserRejectedRequestError(
|
|
2641
|
+
"User rejected the grantee registration transaction"
|
|
2642
|
+
);
|
|
2643
|
+
}
|
|
2644
|
+
throw new BlockchainError(
|
|
2645
|
+
`Failed to register grantee: ${error.message}`,
|
|
2646
|
+
error
|
|
2647
|
+
);
|
|
2648
|
+
}
|
|
2649
|
+
throw new BlockchainError(`Failed to register grantee: ${String(error)}`);
|
|
2650
|
+
}
|
|
2446
2651
|
}
|
|
2447
2652
|
// TODO: When DataPortabilityGrantees contract adds registerGranteeWithSignature function,
|
|
2448
2653
|
// implement submitRegisterGranteeWithSignature and submitSignedRegisterGrantee methods
|
|
2449
|
-
// to support gasless transactions via relayer
|
|
2654
|
+
// to support EIP-712 signed gasless transactions via relayer.
|
|
2655
|
+
// Current implementation above supports direct gasless transactions (relayer pays gas directly).
|
|
2450
2656
|
/**
|
|
2451
2657
|
* Retrieves all registered grantees from the DataPortabilityGrantees contract.
|
|
2452
2658
|
*
|
|
@@ -2494,27 +2700,52 @@ class PermissionsController extends BaseController {
|
|
|
2494
2700
|
const total = Number(totalCount);
|
|
2495
2701
|
const limit = options.limit ?? 50;
|
|
2496
2702
|
const offset = options.offset ?? 0;
|
|
2497
|
-
const
|
|
2498
|
-
const
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2703
|
+
const includePermissions = options.includePermissions ?? true;
|
|
2704
|
+
const startId = total - offset;
|
|
2705
|
+
const endId = Math.max(startId - limit + 1, 1);
|
|
2706
|
+
const granteeIds = Array.from(
|
|
2707
|
+
{ length: startId - endId + 1 },
|
|
2708
|
+
(_, i) => startId - i
|
|
2709
|
+
// Generate IDs in descending order
|
|
2710
|
+
);
|
|
2711
|
+
let grantees;
|
|
2712
|
+
if (includePermissions) {
|
|
2713
|
+
const granteePromises = granteeIds.map(
|
|
2714
|
+
(granteeId) => this.getGranteeById(granteeId)
|
|
2715
|
+
);
|
|
2716
|
+
const granteeResults = await Promise.all(granteePromises);
|
|
2717
|
+
grantees = granteeResults.filter(
|
|
2718
|
+
(grantee) => grantee !== null
|
|
2719
|
+
);
|
|
2720
|
+
} else {
|
|
2721
|
+
const granteeInfoPromises = granteeIds.map(
|
|
2722
|
+
async (granteeId) => {
|
|
2723
|
+
try {
|
|
2724
|
+
const granteeInfo = await this.context.publicClient.readContract({
|
|
2725
|
+
address: DataPortabilityGranteesAddress,
|
|
2726
|
+
abi: DataPortabilityGranteesAbi,
|
|
2727
|
+
functionName: "granteesV2",
|
|
2728
|
+
args: [BigInt(granteeId)]
|
|
2729
|
+
});
|
|
2730
|
+
const grantee = {
|
|
2731
|
+
id: granteeId,
|
|
2732
|
+
owner: granteeInfo.owner,
|
|
2733
|
+
address: granteeInfo.granteeAddress,
|
|
2734
|
+
publicKey: granteeInfo.publicKey,
|
|
2735
|
+
permissionIds: []
|
|
2736
|
+
// TypeScript infers number[] from Grantee type
|
|
2737
|
+
};
|
|
2738
|
+
return grantee;
|
|
2739
|
+
} catch (error) {
|
|
2740
|
+
console.warn(`Failed to fetch grantee ${granteeId}:`, error);
|
|
2741
|
+
return null;
|
|
2742
|
+
}
|
|
2743
|
+
}
|
|
2744
|
+
);
|
|
2745
|
+
const granteeInfoResults = await Promise.all(granteeInfoPromises);
|
|
2746
|
+
grantees = granteeInfoResults.filter(
|
|
2747
|
+
(grantee) => grantee !== null
|
|
2748
|
+
);
|
|
2518
2749
|
}
|
|
2519
2750
|
return {
|
|
2520
2751
|
grantees,
|
|
@@ -2525,15 +2756,16 @@ class PermissionsController extends BaseController {
|
|
|
2525
2756
|
};
|
|
2526
2757
|
}
|
|
2527
2758
|
/**
|
|
2528
|
-
* Retrieves a specific grantee by their Ethereum address
|
|
2759
|
+
* Retrieves a specific grantee by their Ethereum wallet address.
|
|
2529
2760
|
*
|
|
2761
|
+
* @remarks
|
|
2530
2762
|
* Looks up a registered grantee (application) using their Ethereum address
|
|
2531
|
-
* and returns their complete registration information including permissions.
|
|
2763
|
+
* and returns their complete registration information including all associated permissions.
|
|
2532
2764
|
*
|
|
2533
|
-
*
|
|
2534
|
-
*
|
|
2535
|
-
* @
|
|
2536
|
-
* @
|
|
2765
|
+
* Returns `null` if the address is not registered as a grantee or if an error occurs.
|
|
2766
|
+
*
|
|
2767
|
+
* @param granteeAddress - Ethereum wallet address of the grantee to query
|
|
2768
|
+
* @returns Grantee information including ID, addresses, public key, and permission IDs, or `null` if not found
|
|
2537
2769
|
*
|
|
2538
2770
|
* @example
|
|
2539
2771
|
* ```typescript
|
|
@@ -2558,40 +2790,32 @@ class PermissionsController extends BaseController {
|
|
|
2558
2790
|
);
|
|
2559
2791
|
const DataPortabilityGranteesAbi = getAbi("DataPortabilityGrantees");
|
|
2560
2792
|
try {
|
|
2561
|
-
const granteeInfo = await this.context.publicClient.readContract({
|
|
2562
|
-
address: DataPortabilityGranteesAddress,
|
|
2563
|
-
abi: DataPortabilityGranteesAbi,
|
|
2564
|
-
functionName: "granteeByAddress",
|
|
2565
|
-
args: [granteeAddress]
|
|
2566
|
-
});
|
|
2567
2793
|
const granteeId = await this.context.publicClient.readContract({
|
|
2568
2794
|
address: DataPortabilityGranteesAddress,
|
|
2569
2795
|
abi: DataPortabilityGranteesAbi,
|
|
2570
2796
|
functionName: "granteeAddressToId",
|
|
2571
2797
|
args: [granteeAddress]
|
|
2572
2798
|
});
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
publicKey: granteeInfo.publicKey,
|
|
2578
|
-
permissionIds: granteeInfo.permissionIds.map((id) => Number(id))
|
|
2579
|
-
};
|
|
2799
|
+
if (granteeId === 0n) {
|
|
2800
|
+
return null;
|
|
2801
|
+
}
|
|
2802
|
+
return await this.getGranteeById(Number(granteeId));
|
|
2580
2803
|
} catch (error) {
|
|
2581
2804
|
console.warn(`Failed to fetch grantee ${granteeAddress}:`, error);
|
|
2582
2805
|
return null;
|
|
2583
2806
|
}
|
|
2584
2807
|
}
|
|
2585
2808
|
/**
|
|
2586
|
-
* Retrieves a specific grantee by their unique ID
|
|
2809
|
+
* Retrieves a specific grantee by their unique ID.
|
|
2587
2810
|
*
|
|
2811
|
+
* @remarks
|
|
2588
2812
|
* Looks up a registered grantee (application) using their numeric ID assigned during
|
|
2589
|
-
* registration and returns their complete information including permissions.
|
|
2813
|
+
* registration and returns their complete information including all associated permissions.
|
|
2590
2814
|
*
|
|
2591
|
-
*
|
|
2592
|
-
*
|
|
2593
|
-
* @
|
|
2594
|
-
* @
|
|
2815
|
+
* Returns `null` if the grantee is not found or if an error occurs during fetching.
|
|
2816
|
+
*
|
|
2817
|
+
* @param granteeId - Unique numeric ID of the grantee (1-indexed)
|
|
2818
|
+
* @returns Grantee information including ID, addresses, public key, and permission IDs, or `null` if not found
|
|
2595
2819
|
*
|
|
2596
2820
|
* @example
|
|
2597
2821
|
* ```typescript
|
|
@@ -2599,7 +2823,7 @@ class PermissionsController extends BaseController {
|
|
|
2599
2823
|
*
|
|
2600
2824
|
* if (grantee) {
|
|
2601
2825
|
* console.log(`Grantee ID: ${grantee.id}`);
|
|
2602
|
-
* console.log(`Address: ${grantee.
|
|
2826
|
+
* console.log(`Address: ${grantee.address}`);
|
|
2603
2827
|
* console.log(`Owner: ${grantee.owner}`);
|
|
2604
2828
|
* console.log(`Total permissions: ${grantee.permissionIds.length}`);
|
|
2605
2829
|
* } else {
|
|
@@ -2615,18 +2839,23 @@ class PermissionsController extends BaseController {
|
|
|
2615
2839
|
);
|
|
2616
2840
|
const DataPortabilityGranteesAbi = getAbi("DataPortabilityGrantees");
|
|
2617
2841
|
try {
|
|
2618
|
-
const
|
|
2842
|
+
const granteeInfoResult = await this.context.publicClient.readContract({
|
|
2619
2843
|
address: DataPortabilityGranteesAddress,
|
|
2620
2844
|
abi: DataPortabilityGranteesAbi,
|
|
2621
|
-
functionName: "
|
|
2845
|
+
functionName: "granteesV2",
|
|
2622
2846
|
args: [BigInt(granteeId)]
|
|
2623
2847
|
});
|
|
2848
|
+
const granteeInfo = granteeInfoResult;
|
|
2849
|
+
const allPermissionIdsResult = await this.getGranteePermissionsPaginated(
|
|
2850
|
+
BigInt(granteeId)
|
|
2851
|
+
);
|
|
2852
|
+
const allPermissionIds = allPermissionIdsResult;
|
|
2624
2853
|
return {
|
|
2625
2854
|
id: granteeId,
|
|
2626
2855
|
owner: granteeInfo.owner,
|
|
2627
2856
|
address: granteeInfo.granteeAddress,
|
|
2628
2857
|
publicKey: granteeInfo.publicKey,
|
|
2629
|
-
permissionIds:
|
|
2858
|
+
permissionIds: allPermissionIds.map((id) => Number(id))
|
|
2630
2859
|
};
|
|
2631
2860
|
} catch (error) {
|
|
2632
2861
|
console.warn(`Failed to fetch grantee ${granteeId}:`, error);
|
|
@@ -3023,6 +3252,31 @@ class PermissionsController extends BaseController {
|
|
|
3023
3252
|
);
|
|
3024
3253
|
}
|
|
3025
3254
|
}
|
|
3255
|
+
/**
|
|
3256
|
+
* Retrieves detailed grant file data from IPFS or HTTP storage.
|
|
3257
|
+
*
|
|
3258
|
+
* @remarks
|
|
3259
|
+
* This method automatically uses the SDK's configured downloadRelayer to bypass CORS restrictions.
|
|
3260
|
+
* Use this instead of importing the standalone `retrieveGrantFile` utility.
|
|
3261
|
+
*
|
|
3262
|
+
* @param grantUrl - The grant file URL (from OnChainPermissionGrant.grantUrl)
|
|
3263
|
+
* @returns Promise resolving to the complete grant file with operation details
|
|
3264
|
+
* @throws {NetworkError} When all retrieval attempts fail
|
|
3265
|
+
* @example
|
|
3266
|
+
* ```typescript
|
|
3267
|
+
* const grants = await vana.permissions.getUserPermissionGrantsOnChain();
|
|
3268
|
+
* const grantFile = await vana.permissions.retrieveGrantFile(grants[0].grantUrl);
|
|
3269
|
+
* console.log(`Operation: ${grantFile.operation}`);
|
|
3270
|
+
* ```
|
|
3271
|
+
*/
|
|
3272
|
+
async retrieveGrantFile(grantUrl) {
|
|
3273
|
+
const { retrieveGrantFile: retrieveGrantFileUtil } = await import("../utils/grantFiles");
|
|
3274
|
+
return retrieveGrantFileUtil(
|
|
3275
|
+
grantUrl,
|
|
3276
|
+
void 0,
|
|
3277
|
+
this.context.downloadRelayer
|
|
3278
|
+
);
|
|
3279
|
+
}
|
|
3026
3280
|
/**
|
|
3027
3281
|
* Get all permissions for a specific file (alias for getFilePermissionIds)
|
|
3028
3282
|
*
|
|
@@ -3048,26 +3302,34 @@ class PermissionsController extends BaseController {
|
|
|
3048
3302
|
// DATA PORTABILITY GRANTEES HELPER METHODS
|
|
3049
3303
|
// ===========================
|
|
3050
3304
|
/**
|
|
3051
|
-
*
|
|
3305
|
+
* Retrieves detailed grantee information including all associated permissions.
|
|
3306
|
+
*
|
|
3307
|
+
* @remarks
|
|
3308
|
+
* Returns grantee metadata and associated permission IDs. Uses the newer
|
|
3309
|
+
* paginated contract method internally for efficient permission fetching.
|
|
3052
3310
|
*
|
|
3053
|
-
* @param granteeId -
|
|
3054
|
-
* @returns
|
|
3311
|
+
* @param granteeId - Unique grantee identifier as bigint
|
|
3312
|
+
* @returns Grantee information containing owner address, grantee address, public key, and permission IDs
|
|
3313
|
+
* @throws {BlockchainError} When grantee ID is not found or contract read fails
|
|
3314
|
+
*
|
|
3315
|
+
* @example
|
|
3316
|
+
* ```typescript
|
|
3317
|
+
* const granteeInfo = await vana.permissions.getGranteeInfo(BigInt(1));
|
|
3318
|
+
* console.log(`Grantee ${granteeInfo.granteeAddress} has ${granteeInfo.permissionIds.length} permissions`);
|
|
3319
|
+
* ```
|
|
3055
3320
|
*/
|
|
3056
3321
|
async getGranteeInfo(granteeId) {
|
|
3057
3322
|
try {
|
|
3058
|
-
const
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
args: [granteeId]
|
|
3069
|
-
});
|
|
3070
|
-
return granteeInfo;
|
|
3323
|
+
const grantee = await this.getGranteeById(Number(granteeId));
|
|
3324
|
+
if (!grantee) {
|
|
3325
|
+
throw new Error("Grantee not found");
|
|
3326
|
+
}
|
|
3327
|
+
return {
|
|
3328
|
+
owner: grantee.owner,
|
|
3329
|
+
granteeAddress: grantee.address,
|
|
3330
|
+
publicKey: grantee.publicKey,
|
|
3331
|
+
permissionIds: grantee.permissionIds.map((id) => BigInt(id))
|
|
3332
|
+
};
|
|
3071
3333
|
} catch (error) {
|
|
3072
3334
|
throw new BlockchainError(
|
|
3073
3335
|
`Failed to get grantee info: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
@@ -3076,10 +3338,21 @@ class PermissionsController extends BaseController {
|
|
|
3076
3338
|
}
|
|
3077
3339
|
}
|
|
3078
3340
|
/**
|
|
3079
|
-
*
|
|
3341
|
+
* Retrieves detailed grantee information by wallet address.
|
|
3342
|
+
*
|
|
3343
|
+
* @remarks
|
|
3344
|
+
* Looks up the grantee ID from the provided address, then fetches complete
|
|
3345
|
+
* grantee information including all associated permissions.
|
|
3346
|
+
*
|
|
3347
|
+
* @param granteeAddress - Ethereum wallet address of the grantee to query
|
|
3348
|
+
* @returns Grantee information containing owner address, grantee address, public key, and permission IDs
|
|
3349
|
+
* @throws {BlockchainError} When grantee address is not registered or contract read fails
|
|
3080
3350
|
*
|
|
3081
|
-
* @
|
|
3082
|
-
*
|
|
3351
|
+
* @example
|
|
3352
|
+
* ```typescript
|
|
3353
|
+
* const granteeInfo = await vana.permissions.getGranteeInfoByAddress("0x742d35Cc6634c0532925a3b844Bc9e8e1ee3b2De");
|
|
3354
|
+
* console.log(`Found grantee with ${granteeInfo.permissionIds.length} permissions`);
|
|
3355
|
+
* ```
|
|
3083
3356
|
*/
|
|
3084
3357
|
async getGranteeInfoByAddress(granteeAddress) {
|
|
3085
3358
|
try {
|
|
@@ -3089,13 +3362,26 @@ class PermissionsController extends BaseController {
|
|
|
3089
3362
|
"DataPortabilityGrantees"
|
|
3090
3363
|
);
|
|
3091
3364
|
const DataPortabilityGranteesAbi = getAbi("DataPortabilityGrantees");
|
|
3092
|
-
const
|
|
3365
|
+
const granteeIdResult = await this.context.publicClient.readContract({
|
|
3093
3366
|
address: DataPortabilityGranteesAddress,
|
|
3094
3367
|
abi: DataPortabilityGranteesAbi,
|
|
3095
|
-
functionName: "
|
|
3368
|
+
functionName: "granteeAddressToId",
|
|
3096
3369
|
args: [granteeAddress]
|
|
3097
3370
|
});
|
|
3098
|
-
|
|
3371
|
+
const granteeId = granteeIdResult;
|
|
3372
|
+
if (granteeId === 0n) {
|
|
3373
|
+
throw new Error("Grantee not found");
|
|
3374
|
+
}
|
|
3375
|
+
const grantee = await this.getGranteeById(Number(granteeId));
|
|
3376
|
+
if (!grantee) {
|
|
3377
|
+
throw new Error("Grantee not found");
|
|
3378
|
+
}
|
|
3379
|
+
return {
|
|
3380
|
+
owner: grantee.owner,
|
|
3381
|
+
granteeAddress: grantee.address,
|
|
3382
|
+
publicKey: grantee.publicKey,
|
|
3383
|
+
permissionIds: grantee.permissionIds.map((id) => BigInt(id))
|
|
3384
|
+
};
|
|
3099
3385
|
} catch (error) {
|
|
3100
3386
|
throw new BlockchainError(
|
|
3101
3387
|
`Failed to get grantee info by address: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
@@ -3159,6 +3445,117 @@ class PermissionsController extends BaseController {
|
|
|
3159
3445
|
);
|
|
3160
3446
|
}
|
|
3161
3447
|
}
|
|
3448
|
+
/**
|
|
3449
|
+
* Retrieves permission IDs for a specific grantee with flexible pagination.
|
|
3450
|
+
*
|
|
3451
|
+
* @remarks
|
|
3452
|
+
* **Pagination Behavior:**
|
|
3453
|
+
* Returns different types based on parameters:
|
|
3454
|
+
* - Without offset/limit: Returns `bigint[]` of all permissions using batched multicall
|
|
3455
|
+
* - With offset/limit: Returns paginated object with `permissionIds`, `totalCount`, and `hasMore`
|
|
3456
|
+
*
|
|
3457
|
+
* Uses gas-aware multicall for efficient batch fetching when retrieving all permissions.
|
|
3458
|
+
*
|
|
3459
|
+
* @param granteeId - Grantee ID to get permissions for
|
|
3460
|
+
* @param options - Optional pagination parameters
|
|
3461
|
+
* @param options.offset - Zero-based starting index for pagination. Defaults to 0 when fetching all permissions. Required for single-page requests.
|
|
3462
|
+
* @param options.limit - Maximum number of permission IDs to return per page. Defaults to 100 when fetching all permissions. Required for single-page requests.
|
|
3463
|
+
* @returns When called without options: Array of all permission IDs as `bigint[]`.
|
|
3464
|
+
* When called with offset and limit: Paginated result object containing `permissionIds` array,
|
|
3465
|
+
* `totalCount`, and `hasMore` boolean.
|
|
3466
|
+
* @throws {BlockchainError} When contract read operation fails
|
|
3467
|
+
*
|
|
3468
|
+
* @example
|
|
3469
|
+
* ```typescript
|
|
3470
|
+
* // Fetch all permissions (no pagination params)
|
|
3471
|
+
* const allPermissions = await vana.permissions.getGranteePermissionsPaginated(BigInt(1));
|
|
3472
|
+
* console.log(`Total permissions: ${allPermissions.length}`);
|
|
3473
|
+
*
|
|
3474
|
+
* // Fetch a specific page (with pagination params)
|
|
3475
|
+
* const page = await vana.permissions.getGranteePermissionsPaginated(BigInt(1), {
|
|
3476
|
+
* offset: BigInt(0),
|
|
3477
|
+
* limit: BigInt(100)
|
|
3478
|
+
* });
|
|
3479
|
+
* console.log(`Fetched ${page.permissionIds.length} permissions`);
|
|
3480
|
+
* console.log(`Total: ${page.totalCount}, Has more: ${page.hasMore}`);
|
|
3481
|
+
*
|
|
3482
|
+
* // Fetch next page
|
|
3483
|
+
* if (page.hasMore) {
|
|
3484
|
+
* const nextPage = await vana.permissions.getGranteePermissionsPaginated(BigInt(1), {
|
|
3485
|
+
* offset: BigInt(100),
|
|
3486
|
+
* limit: BigInt(100)
|
|
3487
|
+
* });
|
|
3488
|
+
* }
|
|
3489
|
+
* ```
|
|
3490
|
+
*/
|
|
3491
|
+
async getGranteePermissionsPaginated(granteeId, options) {
|
|
3492
|
+
try {
|
|
3493
|
+
const chainId = await this.context.publicClient.getChainId();
|
|
3494
|
+
const DataPortabilityGranteesAddress = getContractAddress(
|
|
3495
|
+
chainId,
|
|
3496
|
+
"DataPortabilityGrantees"
|
|
3497
|
+
);
|
|
3498
|
+
const DataPortabilityGranteesAbi = getAbi("DataPortabilityGrantees");
|
|
3499
|
+
const fetchOnlyOnePage = options?.offset !== void 0 && options?.limit !== void 0;
|
|
3500
|
+
if (fetchOnlyOnePage) {
|
|
3501
|
+
const result = await this.context.publicClient.readContract({
|
|
3502
|
+
address: DataPortabilityGranteesAddress,
|
|
3503
|
+
abi: DataPortabilityGranteesAbi,
|
|
3504
|
+
functionName: "granteePermissionsPaginated",
|
|
3505
|
+
args: [granteeId, options.offset, options.limit]
|
|
3506
|
+
});
|
|
3507
|
+
const [permissionIds, totalCount2, hasMore] = result;
|
|
3508
|
+
return {
|
|
3509
|
+
permissionIds: [...permissionIds],
|
|
3510
|
+
totalCount: totalCount2,
|
|
3511
|
+
hasMore
|
|
3512
|
+
};
|
|
3513
|
+
}
|
|
3514
|
+
const countResult = await this.context.publicClient.readContract({
|
|
3515
|
+
address: DataPortabilityGranteesAddress,
|
|
3516
|
+
abi: DataPortabilityGranteesAbi,
|
|
3517
|
+
functionName: "granteePermissionsPaginated",
|
|
3518
|
+
args: [granteeId, BigInt(0), BigInt(1)]
|
|
3519
|
+
});
|
|
3520
|
+
const [, totalCount] = countResult;
|
|
3521
|
+
if (totalCount === BigInt(0)) {
|
|
3522
|
+
return [];
|
|
3523
|
+
}
|
|
3524
|
+
const batchSize = options?.limit ?? BigInt(100);
|
|
3525
|
+
const startOffset = options?.offset ?? BigInt(0);
|
|
3526
|
+
const endOffset = totalCount;
|
|
3527
|
+
const numBatches = Math.ceil(
|
|
3528
|
+
Number(endOffset - startOffset) / Number(batchSize)
|
|
3529
|
+
);
|
|
3530
|
+
const paginationCalls = Array.from({ length: numBatches }, (_, i) => ({
|
|
3531
|
+
address: DataPortabilityGranteesAddress,
|
|
3532
|
+
abi: DataPortabilityGranteesAbi,
|
|
3533
|
+
functionName: "granteePermissionsPaginated",
|
|
3534
|
+
args: [
|
|
3535
|
+
granteeId,
|
|
3536
|
+
startOffset + BigInt(i) * batchSize,
|
|
3537
|
+
batchSize
|
|
3538
|
+
]
|
|
3539
|
+
}));
|
|
3540
|
+
const results = await gasAwareMulticall(
|
|
3541
|
+
this.context.publicClient,
|
|
3542
|
+
{
|
|
3543
|
+
contracts: paginationCalls
|
|
3544
|
+
}
|
|
3545
|
+
);
|
|
3546
|
+
const allPermissionIds = [];
|
|
3547
|
+
for (const result of results) {
|
|
3548
|
+
const [permissionIds] = result;
|
|
3549
|
+
allPermissionIds.push(...permissionIds);
|
|
3550
|
+
}
|
|
3551
|
+
return allPermissionIds;
|
|
3552
|
+
} catch (error) {
|
|
3553
|
+
throw new BlockchainError(
|
|
3554
|
+
`Failed to get grantee permissions: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
3555
|
+
error
|
|
3556
|
+
);
|
|
3557
|
+
}
|
|
3558
|
+
}
|
|
3162
3559
|
// ===== DataPortabilityServersImplementation Methods =====
|
|
3163
3560
|
/**
|
|
3164
3561
|
* Get all server IDs for a user
|
|
@@ -3372,7 +3769,7 @@ class PermissionsController extends BaseController {
|
|
|
3372
3769
|
args: [serverId, url],
|
|
3373
3770
|
chain: this.context.walletClient?.chain,
|
|
3374
3771
|
account,
|
|
3375
|
-
...options?.
|
|
3772
|
+
...options?.gas && { gas: options.gas },
|
|
3376
3773
|
...options?.nonce && { nonce: options.nonce },
|
|
3377
3774
|
// Use EIP-1559 if available, otherwise fall back to legacy gasPrice
|
|
3378
3775
|
...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
|
|
@@ -3578,7 +3975,7 @@ class PermissionsController extends BaseController {
|
|
|
3578
3975
|
* @throws {BlockchainError} When permission addition fails
|
|
3579
3976
|
* @throws {NetworkError} When network communication fails
|
|
3580
3977
|
*/
|
|
3581
|
-
async submitSignedAddPermission(typedData, signature) {
|
|
3978
|
+
async submitSignedAddPermission(typedData, signature, options) {
|
|
3582
3979
|
this.assertWallet();
|
|
3583
3980
|
try {
|
|
3584
3981
|
let hash;
|
|
@@ -3593,7 +3990,9 @@ class PermissionsController extends BaseController {
|
|
|
3593
3990
|
if (response.type === "error") {
|
|
3594
3991
|
throw new RelayerError(response.error);
|
|
3595
3992
|
}
|
|
3596
|
-
if (response.type === "
|
|
3993
|
+
if (response.type === "submitted") {
|
|
3994
|
+
hash = response.hash;
|
|
3995
|
+
} else if (response.type === "signed") {
|
|
3597
3996
|
hash = response.hash;
|
|
3598
3997
|
} else {
|
|
3599
3998
|
throw new Error("Unexpected response type from relayer");
|
|
@@ -3601,7 +4000,8 @@ class PermissionsController extends BaseController {
|
|
|
3601
4000
|
} else {
|
|
3602
4001
|
hash = await this.submitDirectAddPermissionTransaction(
|
|
3603
4002
|
typedData,
|
|
3604
|
-
signature
|
|
4003
|
+
signature,
|
|
4004
|
+
options
|
|
3605
4005
|
);
|
|
3606
4006
|
}
|
|
3607
4007
|
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
@@ -3770,7 +4170,9 @@ class PermissionsController extends BaseController {
|
|
|
3770
4170
|
if (response.type === "error") {
|
|
3771
4171
|
throw new RelayerError(response.error);
|
|
3772
4172
|
}
|
|
3773
|
-
if (response.type === "
|
|
4173
|
+
if (response.type === "submitted") {
|
|
4174
|
+
hash = response.hash;
|
|
4175
|
+
} else if (response.type === "signed") {
|
|
3774
4176
|
hash = response.hash;
|
|
3775
4177
|
} else {
|
|
3776
4178
|
throw new Error("Unexpected response type from relayer");
|
|
@@ -3832,7 +4234,7 @@ class PermissionsController extends BaseController {
|
|
|
3832
4234
|
args: [permissionId],
|
|
3833
4235
|
chain: this.context.walletClient?.chain,
|
|
3834
4236
|
account,
|
|
3835
|
-
...options?.
|
|
4237
|
+
...options?.gas && { gas: options.gas },
|
|
3836
4238
|
...options?.nonce && { nonce: options.nonce },
|
|
3837
4239
|
// Use EIP-1559 if available, otherwise fall back to legacy gasPrice
|
|
3838
4240
|
...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
|
|
@@ -3865,7 +4267,7 @@ class PermissionsController extends BaseController {
|
|
|
3865
4267
|
* @param signature - The cryptographic signature authorizing the transaction
|
|
3866
4268
|
* @returns Promise resolving to the transaction hash
|
|
3867
4269
|
*/
|
|
3868
|
-
async submitDirectAddPermissionTransaction(typedData, signature) {
|
|
4270
|
+
async submitDirectAddPermissionTransaction(typedData, signature, options) {
|
|
3869
4271
|
this.assertWallet();
|
|
3870
4272
|
const chainId = await this.context.walletClient.getChainId();
|
|
3871
4273
|
const DataPortabilityPermissionsAddress = getContractAddress(
|
|
@@ -3886,7 +4288,8 @@ class PermissionsController extends BaseController {
|
|
|
3886
4288
|
functionName: "addPermission",
|
|
3887
4289
|
args: [permissionInput, formattedSignature],
|
|
3888
4290
|
account: this.context.walletClient?.account ?? this.context.userAddress,
|
|
3889
|
-
chain: this.context.walletClient?.chain ?? null
|
|
4291
|
+
chain: this.context.walletClient?.chain ?? null,
|
|
4292
|
+
...this.spreadTransactionOptions(options)
|
|
3890
4293
|
});
|
|
3891
4294
|
return hash;
|
|
3892
4295
|
}
|
|
@@ -3921,22 +4324,11 @@ class PermissionsController extends BaseController {
|
|
|
3921
4324
|
address: DataPortabilityPermissionsAddress,
|
|
3922
4325
|
abi: DataPortabilityPermissionsAbi,
|
|
3923
4326
|
functionName: "addServerFilesAndPermissions",
|
|
3924
|
-
// @ts-expect-error - Viem's type inference for nested Permission[][] arrays is incompatible with our Permission type
|
|
3925
4327
|
args: [serverFilesAndPermissionInput, formattedSignature],
|
|
3926
4328
|
account: this.context.walletClient?.account ?? this.context.userAddress,
|
|
3927
4329
|
chain: this.context.walletClient?.chain ?? null,
|
|
3928
|
-
...options?.gasLimit && { gas: options.gasLimit },
|
|
3929
|
-
...options?.nonce && { nonce: options.nonce },
|
|
3930
4330
|
...options?.value && { value: options.value },
|
|
3931
|
-
|
|
3932
|
-
...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
|
|
3933
|
-
...options.maxFeePerGas && {
|
|
3934
|
-
maxFeePerGas: options.maxFeePerGas
|
|
3935
|
-
},
|
|
3936
|
-
...options.maxPriorityFeePerGas && {
|
|
3937
|
-
maxPriorityFeePerGas: options.maxPriorityFeePerGas
|
|
3938
|
-
}
|
|
3939
|
-
} : options?.gasPrice && { gasPrice: options.gasPrice }
|
|
4331
|
+
...this.spreadTransactionOptions(options)
|
|
3940
4332
|
});
|
|
3941
4333
|
return hash;
|
|
3942
4334
|
}
|