@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
|
@@ -33,6 +33,7 @@ __export(permissions_exports, {
|
|
|
33
33
|
module.exports = __toCommonJS(permissions_exports);
|
|
34
34
|
var import_viem = require("viem");
|
|
35
35
|
var import_multicall = require("../utils/multicall");
|
|
36
|
+
var import_pollingManager = require("../core/pollingManager");
|
|
36
37
|
var import_errors = require("../errors");
|
|
37
38
|
var import_addresses = require("../config/addresses");
|
|
38
39
|
var import_abi = require("../generated/abi");
|
|
@@ -80,10 +81,14 @@ class PermissionsController extends import_base.BaseController {
|
|
|
80
81
|
* await vana.permissions.revoke({ permissionId: result.permissionId });
|
|
81
82
|
* ```
|
|
82
83
|
*/
|
|
83
|
-
async grant(params) {
|
|
84
|
+
async grant(params, options) {
|
|
84
85
|
this.assertWallet();
|
|
85
86
|
const { typedData, signature } = await this.createAndSign(params);
|
|
86
|
-
const result = await this.submitSignedGrantWithEvents(
|
|
87
|
+
const result = await this.submitSignedGrantWithEvents(
|
|
88
|
+
typedData,
|
|
89
|
+
signature,
|
|
90
|
+
options
|
|
91
|
+
);
|
|
87
92
|
return result;
|
|
88
93
|
}
|
|
89
94
|
/**
|
|
@@ -111,10 +116,10 @@ class PermissionsController extends import_base.BaseController {
|
|
|
111
116
|
* console.log(`Permission ID: ${eventData.permissionId}`);
|
|
112
117
|
* ```
|
|
113
118
|
*/
|
|
114
|
-
async submitPermissionGrant(params) {
|
|
119
|
+
async submitPermissionGrant(params, options) {
|
|
115
120
|
this.assertWallet();
|
|
116
121
|
const { typedData, signature } = await this.createAndSign(params);
|
|
117
|
-
return await this.submitSignedGrant(typedData, signature);
|
|
122
|
+
return await this.submitSignedGrant(typedData, signature, options);
|
|
118
123
|
}
|
|
119
124
|
/**
|
|
120
125
|
* Prepares a permission grant with preview before signing.
|
|
@@ -141,7 +146,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
141
146
|
* const transactionHash = await confirm();
|
|
142
147
|
* ```
|
|
143
148
|
*/
|
|
144
|
-
async prepareGrant(params) {
|
|
149
|
+
async prepareGrant(params, options) {
|
|
145
150
|
this.assertWallet();
|
|
146
151
|
try {
|
|
147
152
|
const grantFile = (0, import_grantFiles.createGrantFile)(params);
|
|
@@ -149,7 +154,11 @@ class PermissionsController extends import_base.BaseController {
|
|
|
149
154
|
return {
|
|
150
155
|
preview: grantFile,
|
|
151
156
|
confirm: async () => {
|
|
152
|
-
return await this.confirmGrantInternalWithEvents(
|
|
157
|
+
return await this.confirmGrantInternalWithEvents(
|
|
158
|
+
params,
|
|
159
|
+
grantFile,
|
|
160
|
+
options
|
|
161
|
+
);
|
|
153
162
|
}
|
|
154
163
|
};
|
|
155
164
|
} catch (error) {
|
|
@@ -181,7 +190,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
181
190
|
* @throws {NetworkError} When IPFS upload fails
|
|
182
191
|
* @throws {SignatureError} When user rejects the signature
|
|
183
192
|
*/
|
|
184
|
-
async confirmGrantInternal(params, grantFile) {
|
|
193
|
+
async confirmGrantInternal(params, grantFile, options) {
|
|
185
194
|
try {
|
|
186
195
|
let { grantUrl } = params;
|
|
187
196
|
console.debug("\u{1F50D} Debug - Grant URL from params:", grantUrl);
|
|
@@ -206,7 +215,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
206
215
|
if (response.type === "error") {
|
|
207
216
|
throw new Error(response.error);
|
|
208
217
|
}
|
|
209
|
-
if (response.type === "direct" && typeof response.result === "object" && "url" in response.result) {
|
|
218
|
+
if (response.type === "direct" && typeof response.result === "object" && response.result !== null && "url" in response.result) {
|
|
210
219
|
grantUrl = response.result.url;
|
|
211
220
|
} else {
|
|
212
221
|
throw new Error("Invalid response from relayer for grant storage");
|
|
@@ -242,7 +251,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
242
251
|
nonce
|
|
243
252
|
});
|
|
244
253
|
const signature = await this.signTypedData(typedData);
|
|
245
|
-
return await this.submitSignedGrant(typedData, signature);
|
|
254
|
+
return await this.submitSignedGrant(typedData, signature, options);
|
|
246
255
|
} catch (error) {
|
|
247
256
|
if (error instanceof Error) {
|
|
248
257
|
if (error instanceof import_errors.RelayerError || error instanceof import_errors.UserRejectedRequestError || error instanceof import_errors.SerializationError || error instanceof import_errors.SignatureError || error instanceof import_errors.NetworkError || error instanceof import_errors.NonceError) {
|
|
@@ -314,7 +323,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
314
323
|
if (response.type === "error") {
|
|
315
324
|
throw new Error(response.error);
|
|
316
325
|
}
|
|
317
|
-
if (response.type === "direct" && typeof response.result === "object" && "url" in response.result) {
|
|
326
|
+
if (response.type === "direct" && typeof response.result === "object" && response.result !== null && "url" in response.result) {
|
|
318
327
|
grantUrl = response.result.url;
|
|
319
328
|
} else {
|
|
320
329
|
throw new Error("Invalid response from relayer for grant storage");
|
|
@@ -387,7 +396,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
387
396
|
* );
|
|
388
397
|
* ```
|
|
389
398
|
*/
|
|
390
|
-
async submitSignedGrant(typedData, signature) {
|
|
399
|
+
async submitSignedGrant(typedData, signature, options) {
|
|
391
400
|
try {
|
|
392
401
|
console.debug(
|
|
393
402
|
"\u{1F50D} Debug - submitSignedGrant called with typed data:",
|
|
@@ -405,26 +414,41 @@ class PermissionsController extends import_base.BaseController {
|
|
|
405
414
|
signature,
|
|
406
415
|
expectedUserAddress: this.context.userAddress
|
|
407
416
|
});
|
|
408
|
-
|
|
409
|
-
if (response.type === "signed") {
|
|
410
|
-
hash = response.hash;
|
|
411
|
-
} else if (response.type === "error") {
|
|
417
|
+
if (response.type === "error") {
|
|
412
418
|
throw new Error(`Relayer error: ${response.error}`);
|
|
419
|
+
}
|
|
420
|
+
let finalHash;
|
|
421
|
+
if (response.type === "submitted") {
|
|
422
|
+
finalHash = response.hash;
|
|
423
|
+
} else if (response.type === "pending") {
|
|
424
|
+
const pollResult = await this.pollRelayerForConfirmation(
|
|
425
|
+
response.operationId,
|
|
426
|
+
options
|
|
427
|
+
);
|
|
428
|
+
finalHash = pollResult.hash;
|
|
429
|
+
} else if (response.type === "confirmed") {
|
|
430
|
+
finalHash = response.hash;
|
|
431
|
+
} else if (response.type === "signed") {
|
|
432
|
+
finalHash = response.hash;
|
|
413
433
|
} else {
|
|
414
434
|
throw new Error(
|
|
415
|
-
"Invalid response from relayer:
|
|
435
|
+
"Invalid response from relayer: unexpected response type"
|
|
416
436
|
);
|
|
417
437
|
}
|
|
418
438
|
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
419
439
|
const { tx } = await import("../utils/transactionHelpers");
|
|
420
440
|
return tx({
|
|
421
|
-
hash,
|
|
441
|
+
hash: finalHash,
|
|
422
442
|
from: typeof account === "string" ? account : account.address,
|
|
423
443
|
contract: "DataPortabilityPermissions",
|
|
424
444
|
fn: "addPermission"
|
|
425
445
|
});
|
|
426
446
|
} else {
|
|
427
|
-
return await this.submitDirectTransaction(
|
|
447
|
+
return await this.submitDirectTransaction(
|
|
448
|
+
typedData,
|
|
449
|
+
signature,
|
|
450
|
+
options
|
|
451
|
+
);
|
|
428
452
|
}
|
|
429
453
|
} catch (error) {
|
|
430
454
|
if (error instanceof import_errors.RelayerError || error instanceof import_errors.NetworkError || error instanceof import_errors.UserRejectedRequestError || error instanceof import_errors.SignatureError || error instanceof import_errors.NonceError) {
|
|
@@ -457,7 +481,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
457
481
|
* const result = await txHandle.waitForEvents();
|
|
458
482
|
* ```
|
|
459
483
|
*/
|
|
460
|
-
async submitSignedTrustServer(typedData, signature) {
|
|
484
|
+
async submitSignedTrustServer(typedData, signature, options) {
|
|
461
485
|
try {
|
|
462
486
|
const trustServerInput = {
|
|
463
487
|
nonce: BigInt(typedData.message.nonce),
|
|
@@ -465,7 +489,8 @@ class PermissionsController extends import_base.BaseController {
|
|
|
465
489
|
};
|
|
466
490
|
const hash = await this.submitTrustServerTransaction(
|
|
467
491
|
trustServerInput,
|
|
468
|
-
signature
|
|
492
|
+
signature,
|
|
493
|
+
options
|
|
469
494
|
);
|
|
470
495
|
const account = this.context.userAddress;
|
|
471
496
|
const { tx } = await import("../utils/transactionHelpers");
|
|
@@ -520,7 +545,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
520
545
|
* const result = await txHandle.waitForEvents();
|
|
521
546
|
* ```
|
|
522
547
|
*/
|
|
523
|
-
async submitSignedAddAndTrustServer(typedData, signature) {
|
|
548
|
+
async submitSignedAddAndTrustServer(typedData, signature, options) {
|
|
524
549
|
try {
|
|
525
550
|
const addAndTrustServerInput = {
|
|
526
551
|
nonce: BigInt(typedData.message.nonce),
|
|
@@ -530,7 +555,8 @@ class PermissionsController extends import_base.BaseController {
|
|
|
530
555
|
};
|
|
531
556
|
const hash = await this.submitAddAndTrustServerTransaction(
|
|
532
557
|
addAndTrustServerInput,
|
|
533
|
-
signature
|
|
558
|
+
signature,
|
|
559
|
+
options
|
|
534
560
|
);
|
|
535
561
|
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
536
562
|
const { tx } = await import("../utils/transactionHelpers");
|
|
@@ -558,8 +584,12 @@ class PermissionsController extends import_base.BaseController {
|
|
|
558
584
|
* @param signature - The user's signature authorizing the transaction
|
|
559
585
|
* @returns Promise resolving to PermissionGrantResult with parsed events
|
|
560
586
|
*/
|
|
561
|
-
async submitSignedGrantWithEvents(typedData, signature) {
|
|
562
|
-
const txResult = await this.submitSignedGrant(
|
|
587
|
+
async submitSignedGrantWithEvents(typedData, signature, options) {
|
|
588
|
+
const txResult = await this.submitSignedGrant(
|
|
589
|
+
typedData,
|
|
590
|
+
signature,
|
|
591
|
+
options
|
|
592
|
+
);
|
|
563
593
|
if (!this.context.waitForTransactionEvents) {
|
|
564
594
|
throw new import_errors.BlockchainError("waitForTransactionEvents not configured");
|
|
565
595
|
}
|
|
@@ -591,8 +621,12 @@ class PermissionsController extends import_base.BaseController {
|
|
|
591
621
|
* @param grantFile - The pre-created grant file object
|
|
592
622
|
* @returns Promise resolving to PermissionGrantResult with parsed events
|
|
593
623
|
*/
|
|
594
|
-
async confirmGrantInternalWithEvents(params, grantFile) {
|
|
595
|
-
const txResult = await this.confirmGrantInternal(
|
|
624
|
+
async confirmGrantInternalWithEvents(params, grantFile, options) {
|
|
625
|
+
const txResult = await this.confirmGrantInternal(
|
|
626
|
+
params,
|
|
627
|
+
grantFile,
|
|
628
|
+
options
|
|
629
|
+
);
|
|
596
630
|
if (!this.context.waitForTransactionEvents) {
|
|
597
631
|
throw new import_errors.BlockchainError("waitForTransactionEvents not configured");
|
|
598
632
|
}
|
|
@@ -616,6 +650,27 @@ class PermissionsController extends import_base.BaseController {
|
|
|
616
650
|
fileIds: event.fileIds
|
|
617
651
|
};
|
|
618
652
|
}
|
|
653
|
+
/**
|
|
654
|
+
* Polls the relayer for confirmation of a pending operation.
|
|
655
|
+
*
|
|
656
|
+
* @param operationId - The operation ID to poll
|
|
657
|
+
* @param options - Polling configuration including status updates and cancellation
|
|
658
|
+
* @returns Promise resolving to the confirmed hash and receipt
|
|
659
|
+
* @throws {TransactionPendingError} When the operation times out
|
|
660
|
+
* @throws {Error} When the operation fails or is cancelled
|
|
661
|
+
* @internal
|
|
662
|
+
*/
|
|
663
|
+
async pollRelayerForConfirmation(operationId, options) {
|
|
664
|
+
if (!this.context.relayer) {
|
|
665
|
+
throw new Error("Relayer not configured for polling");
|
|
666
|
+
}
|
|
667
|
+
const pollingManager = new import_pollingManager.PollingManager(this.context.relayer);
|
|
668
|
+
return await pollingManager.startPolling(operationId, {
|
|
669
|
+
signal: options?.signal,
|
|
670
|
+
onStatusUpdate: options?.onStatusUpdate,
|
|
671
|
+
...options?.pollingOptions
|
|
672
|
+
});
|
|
673
|
+
}
|
|
619
674
|
/**
|
|
620
675
|
* Submits an already-signed permission revoke transaction to the blockchain.
|
|
621
676
|
*
|
|
@@ -637,7 +692,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
637
692
|
* const result = await txHandle.waitForEvents();
|
|
638
693
|
* ```
|
|
639
694
|
*/
|
|
640
|
-
async submitSignedRevoke(typedData, signature) {
|
|
695
|
+
async submitSignedRevoke(typedData, signature, options) {
|
|
641
696
|
try {
|
|
642
697
|
let hash;
|
|
643
698
|
if (this.context.relayer) {
|
|
@@ -648,19 +703,31 @@ class PermissionsController extends import_base.BaseController {
|
|
|
648
703
|
signature,
|
|
649
704
|
expectedUserAddress: this.context.userAddress
|
|
650
705
|
});
|
|
651
|
-
if (response.type === "
|
|
652
|
-
hash = response.hash;
|
|
653
|
-
} else if (response.type === "error") {
|
|
706
|
+
if (response.type === "error") {
|
|
654
707
|
throw new Error(`Relayer error: ${response.error}`);
|
|
708
|
+
}
|
|
709
|
+
if (response.type === "submitted") {
|
|
710
|
+
hash = response.hash;
|
|
711
|
+
} else if (response.type === "pending") {
|
|
712
|
+
const pollResult = await this.pollRelayerForConfirmation(
|
|
713
|
+
response.operationId,
|
|
714
|
+
options
|
|
715
|
+
);
|
|
716
|
+
hash = pollResult.hash;
|
|
717
|
+
} else if (response.type === "confirmed") {
|
|
718
|
+
hash = response.hash;
|
|
719
|
+
} else if (response.type === "signed") {
|
|
720
|
+
hash = response.hash;
|
|
655
721
|
} else {
|
|
656
722
|
throw new Error(
|
|
657
|
-
"Invalid response from relayer:
|
|
723
|
+
"Invalid response from relayer: unexpected response type"
|
|
658
724
|
);
|
|
659
725
|
}
|
|
660
726
|
} else {
|
|
661
727
|
hash = await this.submitDirectRevokeTransaction(
|
|
662
728
|
typedData,
|
|
663
|
-
signature
|
|
729
|
+
signature,
|
|
730
|
+
options
|
|
664
731
|
);
|
|
665
732
|
}
|
|
666
733
|
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
@@ -702,7 +769,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
702
769
|
* const result = await txHandle.waitForEvents();
|
|
703
770
|
* ```
|
|
704
771
|
*/
|
|
705
|
-
async submitSignedUntrustServer(typedData, signature) {
|
|
772
|
+
async submitSignedUntrustServer(typedData, signature, options) {
|
|
706
773
|
try {
|
|
707
774
|
let hash;
|
|
708
775
|
if (this.context.relayer) {
|
|
@@ -713,7 +780,9 @@ class PermissionsController extends import_base.BaseController {
|
|
|
713
780
|
signature,
|
|
714
781
|
expectedUserAddress: this.context.userAddress
|
|
715
782
|
});
|
|
716
|
-
if (response.type === "
|
|
783
|
+
if (response.type === "submitted") {
|
|
784
|
+
hash = response.hash;
|
|
785
|
+
} else if (response.type === "signed") {
|
|
717
786
|
hash = response.hash;
|
|
718
787
|
} else if (response.type === "error") {
|
|
719
788
|
throw new Error(`Relayer error: ${response.error}`);
|
|
@@ -725,7 +794,8 @@ class PermissionsController extends import_base.BaseController {
|
|
|
725
794
|
} else {
|
|
726
795
|
hash = await this.submitSignedUntrustTransaction(
|
|
727
796
|
typedData,
|
|
728
|
-
signature
|
|
797
|
+
signature,
|
|
798
|
+
options
|
|
729
799
|
);
|
|
730
800
|
}
|
|
731
801
|
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
@@ -758,7 +828,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
758
828
|
* @returns Promise resolving to the transaction hash
|
|
759
829
|
* @throws {BlockchainError} When contract submission fails
|
|
760
830
|
*/
|
|
761
|
-
async submitDirectTransaction(typedData, signature) {
|
|
831
|
+
async submitDirectTransaction(typedData, signature, options) {
|
|
762
832
|
this.assertWallet();
|
|
763
833
|
const chainId = await this.context.publicClient.getChainId();
|
|
764
834
|
const DataPortabilityPermissionsAddress = (0, import_addresses.getContractAddress)(
|
|
@@ -790,7 +860,8 @@ class PermissionsController extends import_base.BaseController {
|
|
|
790
860
|
functionName: "addPermission",
|
|
791
861
|
args: [permissionInput, formattedSignature],
|
|
792
862
|
account,
|
|
793
|
-
chain: this.context.walletClient?.chain ?? null
|
|
863
|
+
chain: this.context.walletClient?.chain ?? null,
|
|
864
|
+
...this.spreadTransactionOptions(options)
|
|
794
865
|
});
|
|
795
866
|
const { tx } = await import("../utils/transactionHelpers");
|
|
796
867
|
return tx({
|
|
@@ -889,7 +960,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
889
960
|
args: [params.permissionId],
|
|
890
961
|
account,
|
|
891
962
|
chain: this.context.walletClient?.chain ?? null,
|
|
892
|
-
...options?.
|
|
963
|
+
...options?.gas && { gas: options.gas },
|
|
893
964
|
...options?.nonce && { nonce: options.nonce },
|
|
894
965
|
// Use EIP-1559 if available, otherwise fall back to legacy gasPrice
|
|
895
966
|
...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
|
|
@@ -946,7 +1017,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
946
1017
|
* console.log(`Permission ${result.permissionId} revoked`);
|
|
947
1018
|
* ```
|
|
948
1019
|
*/
|
|
949
|
-
async submitRevokeWithSignature(params) {
|
|
1020
|
+
async submitRevokeWithSignature(params, options) {
|
|
950
1021
|
this.assertWallet();
|
|
951
1022
|
try {
|
|
952
1023
|
if (!this.context.walletClient?.chain?.id) {
|
|
@@ -978,7 +1049,9 @@ class PermissionsController extends import_base.BaseController {
|
|
|
978
1049
|
signature,
|
|
979
1050
|
expectedUserAddress: this.context.userAddress
|
|
980
1051
|
});
|
|
981
|
-
if (response.type === "
|
|
1052
|
+
if (response.type === "submitted") {
|
|
1053
|
+
hash = response.hash;
|
|
1054
|
+
} else if (response.type === "signed") {
|
|
982
1055
|
hash = response.hash;
|
|
983
1056
|
} else if (response.type === "error") {
|
|
984
1057
|
throw new Error(`Relayer error: ${response.error}`);
|
|
@@ -990,7 +1063,8 @@ class PermissionsController extends import_base.BaseController {
|
|
|
990
1063
|
} else {
|
|
991
1064
|
hash = await this.submitDirectRevokeTransaction(
|
|
992
1065
|
typedData,
|
|
993
|
-
signature
|
|
1066
|
+
signature,
|
|
1067
|
+
options
|
|
994
1068
|
);
|
|
995
1069
|
}
|
|
996
1070
|
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
@@ -1316,7 +1390,9 @@ class PermissionsController extends import_base.BaseController {
|
|
|
1316
1390
|
* ```
|
|
1317
1391
|
*/
|
|
1318
1392
|
async getUserPermissionGrantsOnChain(options = {}) {
|
|
1319
|
-
const { limit = 50, subgraphUrl } = options;
|
|
1393
|
+
const { limit = 50, fetchAll = false, subgraphUrl } = options;
|
|
1394
|
+
const pageSize = fetchAll ? 100 : limit;
|
|
1395
|
+
const maxResults = fetchAll ? 1e4 : limit;
|
|
1320
1396
|
try {
|
|
1321
1397
|
const userAddress = this.context.userAddress;
|
|
1322
1398
|
const graphqlEndpoint = subgraphUrl ?? this.context.subgraphUrl;
|
|
@@ -1326,10 +1402,10 @@ class PermissionsController extends import_base.BaseController {
|
|
|
1326
1402
|
);
|
|
1327
1403
|
}
|
|
1328
1404
|
const query = `
|
|
1329
|
-
query GetUserPermissions($userId: ID!) {
|
|
1405
|
+
query GetUserPermissions($userId: ID!, $first: Int!, $skip: Int!) {
|
|
1330
1406
|
user(id: $userId) {
|
|
1331
1407
|
id
|
|
1332
|
-
permissions {
|
|
1408
|
+
permissions(first: $first, skip: $skip, orderBy: addedAtBlock, orderDirection: desc) {
|
|
1333
1409
|
id
|
|
1334
1410
|
grant
|
|
1335
1411
|
nonce
|
|
@@ -1347,34 +1423,82 @@ class PermissionsController extends import_base.BaseController {
|
|
|
1347
1423
|
}
|
|
1348
1424
|
}
|
|
1349
1425
|
`;
|
|
1350
|
-
const
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1426
|
+
const allPermissions = [];
|
|
1427
|
+
let currentOffset = 0;
|
|
1428
|
+
if (!fetchAll) {
|
|
1429
|
+
const response = await fetch(graphqlEndpoint, {
|
|
1430
|
+
method: "POST",
|
|
1431
|
+
headers: {
|
|
1432
|
+
"Content-Type": "application/json"
|
|
1433
|
+
},
|
|
1434
|
+
body: JSON.stringify({
|
|
1435
|
+
query,
|
|
1436
|
+
variables: {
|
|
1437
|
+
userId: userAddress.toLowerCase(),
|
|
1438
|
+
first: limit,
|
|
1439
|
+
skip: 0
|
|
1440
|
+
}
|
|
1441
|
+
})
|
|
1442
|
+
});
|
|
1443
|
+
if (!response.ok) {
|
|
1444
|
+
throw new import_errors.BlockchainError(
|
|
1445
|
+
`Subgraph request failed: ${response.status} ${response.statusText}`
|
|
1446
|
+
);
|
|
1447
|
+
}
|
|
1448
|
+
const result = await response.json();
|
|
1449
|
+
if (result.errors) {
|
|
1450
|
+
throw new import_errors.BlockchainError(
|
|
1451
|
+
`Subgraph errors: ${result.errors.map((e) => e.message).join(", ")}`
|
|
1452
|
+
);
|
|
1453
|
+
}
|
|
1454
|
+
const userData = result.data?.user;
|
|
1455
|
+
if (!userData?.permissions?.length) {
|
|
1456
|
+
return [];
|
|
1457
|
+
}
|
|
1458
|
+
allPermissions.push(...userData.permissions);
|
|
1459
|
+
} else {
|
|
1460
|
+
while (allPermissions.length < maxResults) {
|
|
1461
|
+
const currentLimit = Math.min(
|
|
1462
|
+
pageSize,
|
|
1463
|
+
maxResults - allPermissions.length
|
|
1464
|
+
);
|
|
1465
|
+
const response = await fetch(graphqlEndpoint, {
|
|
1466
|
+
method: "POST",
|
|
1467
|
+
headers: {
|
|
1468
|
+
"Content-Type": "application/json"
|
|
1469
|
+
},
|
|
1470
|
+
body: JSON.stringify({
|
|
1471
|
+
query,
|
|
1472
|
+
variables: {
|
|
1473
|
+
userId: userAddress.toLowerCase(),
|
|
1474
|
+
first: currentLimit,
|
|
1475
|
+
skip: currentOffset
|
|
1476
|
+
}
|
|
1477
|
+
})
|
|
1478
|
+
});
|
|
1479
|
+
if (!response.ok) {
|
|
1480
|
+
throw new import_errors.BlockchainError(
|
|
1481
|
+
`Subgraph request failed: ${response.status} ${response.statusText}`
|
|
1482
|
+
);
|
|
1359
1483
|
}
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1484
|
+
const result = await response.json();
|
|
1485
|
+
if (result.errors) {
|
|
1486
|
+
throw new import_errors.BlockchainError(
|
|
1487
|
+
`Subgraph errors: ${result.errors.map((e) => e.message).join(", ")}`
|
|
1488
|
+
);
|
|
1489
|
+
}
|
|
1490
|
+
const userData = result.data?.user;
|
|
1491
|
+
if (!userData?.permissions?.length) {
|
|
1492
|
+
break;
|
|
1493
|
+
}
|
|
1494
|
+
allPermissions.push(...userData.permissions);
|
|
1495
|
+
if (userData.permissions.length < currentLimit) {
|
|
1496
|
+
break;
|
|
1497
|
+
}
|
|
1498
|
+
currentOffset += userData.permissions.length;
|
|
1499
|
+
}
|
|
1376
1500
|
}
|
|
1377
|
-
const onChainGrants =
|
|
1501
|
+
const onChainGrants = allPermissions.map(
|
|
1378
1502
|
(permission) => ({
|
|
1379
1503
|
id: BigInt(permission.id),
|
|
1380
1504
|
grantUrl: permission.grant,
|
|
@@ -1555,7 +1679,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
1555
1679
|
* @param params - Parameters for adding and trusting the server
|
|
1556
1680
|
* @returns Promise resolving to TransactionResult with ServerTrustResult event data
|
|
1557
1681
|
*/
|
|
1558
|
-
async submitAddAndTrustServerWithSignature(params) {
|
|
1682
|
+
async submitAddAndTrustServerWithSignature(params, options) {
|
|
1559
1683
|
this.assertWallet();
|
|
1560
1684
|
try {
|
|
1561
1685
|
const nonce = await this.getServersUserNonce();
|
|
@@ -1591,7 +1715,9 @@ class PermissionsController extends import_base.BaseController {
|
|
|
1591
1715
|
if (response.type === "error") {
|
|
1592
1716
|
throw new import_errors.RelayerError(response.error);
|
|
1593
1717
|
}
|
|
1594
|
-
if (response.type === "
|
|
1718
|
+
if (response.type === "submitted") {
|
|
1719
|
+
hash = response.hash;
|
|
1720
|
+
} else if (response.type === "signed") {
|
|
1595
1721
|
hash = response.hash;
|
|
1596
1722
|
} else {
|
|
1597
1723
|
throw new Error("Unexpected response type from relayer");
|
|
@@ -1599,7 +1725,8 @@ class PermissionsController extends import_base.BaseController {
|
|
|
1599
1725
|
} else {
|
|
1600
1726
|
hash = await this.submitAddAndTrustServerTransaction(
|
|
1601
1727
|
addAndTrustServerInput,
|
|
1602
|
-
signature
|
|
1728
|
+
signature,
|
|
1729
|
+
options
|
|
1603
1730
|
);
|
|
1604
1731
|
}
|
|
1605
1732
|
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
@@ -1638,7 +1765,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
1638
1765
|
* @throws {ServerUrlMismatchError} When server URL doesn't match existing registration
|
|
1639
1766
|
* @throws {BlockchainError} When trust operation fails for any other reason
|
|
1640
1767
|
*/
|
|
1641
|
-
async submitTrustServerWithSignature(params) {
|
|
1768
|
+
async submitTrustServerWithSignature(params, options) {
|
|
1642
1769
|
this.assertWallet();
|
|
1643
1770
|
try {
|
|
1644
1771
|
const nonce = await this.getServersUserNonce();
|
|
@@ -1660,7 +1787,9 @@ class PermissionsController extends import_base.BaseController {
|
|
|
1660
1787
|
if (response.type === "error") {
|
|
1661
1788
|
throw new import_errors.RelayerError(response.error);
|
|
1662
1789
|
}
|
|
1663
|
-
if (response.type === "
|
|
1790
|
+
if (response.type === "submitted") {
|
|
1791
|
+
hash = response.hash;
|
|
1792
|
+
} else if (response.type === "signed") {
|
|
1664
1793
|
hash = response.hash;
|
|
1665
1794
|
} else {
|
|
1666
1795
|
throw new Error("Unexpected response type from relayer");
|
|
@@ -1668,7 +1797,8 @@ class PermissionsController extends import_base.BaseController {
|
|
|
1668
1797
|
} else {
|
|
1669
1798
|
hash = await this.submitTrustServerTransaction(
|
|
1670
1799
|
trustServerInput,
|
|
1671
|
-
signature
|
|
1800
|
+
signature,
|
|
1801
|
+
options
|
|
1672
1802
|
);
|
|
1673
1803
|
}
|
|
1674
1804
|
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
@@ -1726,7 +1856,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
1726
1856
|
args: [BigInt(params.serverId)],
|
|
1727
1857
|
account,
|
|
1728
1858
|
chain: this.context.walletClient?.chain ?? null,
|
|
1729
|
-
...options?.
|
|
1859
|
+
...options?.gas && { gas: options.gas },
|
|
1730
1860
|
...options?.nonce && { nonce: options.nonce },
|
|
1731
1861
|
// Use EIP-1559 if available, otherwise fall back to legacy gasPrice
|
|
1732
1862
|
...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
|
|
@@ -1830,7 +1960,9 @@ class PermissionsController extends import_base.BaseController {
|
|
|
1830
1960
|
if (response.type === "error") {
|
|
1831
1961
|
throw new import_errors.RelayerError(response.error);
|
|
1832
1962
|
}
|
|
1833
|
-
if (response.type === "
|
|
1963
|
+
if (response.type === "submitted") {
|
|
1964
|
+
hash = response.hash;
|
|
1965
|
+
} else if (response.type === "signed") {
|
|
1834
1966
|
hash = response.hash;
|
|
1835
1967
|
} else {
|
|
1836
1968
|
throw new Error("Unexpected response type from relayer");
|
|
@@ -2276,7 +2408,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
2276
2408
|
* @param signature - The cryptographic signature for the transaction
|
|
2277
2409
|
* @returns Promise resolving to the transaction hash
|
|
2278
2410
|
*/
|
|
2279
|
-
async submitAddAndTrustServerTransaction(addAndTrustServerInput, signature) {
|
|
2411
|
+
async submitAddAndTrustServerTransaction(addAndTrustServerInput, signature, options) {
|
|
2280
2412
|
this.assertWallet();
|
|
2281
2413
|
const chainId = await this.context.walletClient.getChainId();
|
|
2282
2414
|
const DataPortabilityServersAddress = (0, import_addresses.getContractAddress)(
|
|
@@ -2310,7 +2442,16 @@ class PermissionsController extends import_base.BaseController {
|
|
|
2310
2442
|
formattedSignature
|
|
2311
2443
|
],
|
|
2312
2444
|
account: this.context.walletClient?.account ?? this.context.userAddress,
|
|
2313
|
-
chain: this.context.walletClient?.chain ?? null
|
|
2445
|
+
chain: this.context.walletClient?.chain ?? null,
|
|
2446
|
+
...options && {
|
|
2447
|
+
gas: options.gas,
|
|
2448
|
+
nonce: options.nonce,
|
|
2449
|
+
// Use EIP-1559 gas pricing if available, otherwise legacy
|
|
2450
|
+
...options.maxFeePerGas || options.maxPriorityFeePerGas ? {
|
|
2451
|
+
maxFeePerGas: options.maxFeePerGas,
|
|
2452
|
+
maxPriorityFeePerGas: options.maxPriorityFeePerGas
|
|
2453
|
+
} : options.gasPrice ? { gasPrice: options.gasPrice } : {}
|
|
2454
|
+
}
|
|
2314
2455
|
});
|
|
2315
2456
|
return txHash;
|
|
2316
2457
|
}
|
|
@@ -2321,7 +2462,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
2321
2462
|
* @param signature - The cryptographic signature for the transaction
|
|
2322
2463
|
* @returns Promise resolving to the transaction hash
|
|
2323
2464
|
*/
|
|
2324
|
-
async submitTrustServerTransaction(trustServerInput, signature) {
|
|
2465
|
+
async submitTrustServerTransaction(trustServerInput, signature, options) {
|
|
2325
2466
|
this.assertWallet();
|
|
2326
2467
|
const chainId = await this.context.walletClient.getChainId();
|
|
2327
2468
|
const DataPortabilityServersAddress = (0, import_addresses.getContractAddress)(
|
|
@@ -2342,7 +2483,8 @@ class PermissionsController extends import_base.BaseController {
|
|
|
2342
2483
|
formattedSignature
|
|
2343
2484
|
],
|
|
2344
2485
|
account: this.context.walletClient?.account ?? this.context.userAddress,
|
|
2345
|
-
chain: this.context.walletClient?.chain ?? null
|
|
2486
|
+
chain: this.context.walletClient?.chain ?? null,
|
|
2487
|
+
...this.spreadTransactionOptions(options)
|
|
2346
2488
|
});
|
|
2347
2489
|
return txHash;
|
|
2348
2490
|
}
|
|
@@ -2353,7 +2495,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
2353
2495
|
* @param signature - The cryptographic signature authorizing the revoke
|
|
2354
2496
|
* @returns Promise resolving to the transaction hash
|
|
2355
2497
|
*/
|
|
2356
|
-
async submitDirectRevokeTransaction(typedData, signature) {
|
|
2498
|
+
async submitDirectRevokeTransaction(typedData, signature, options) {
|
|
2357
2499
|
this.assertWallet();
|
|
2358
2500
|
const chainId = await this.context.walletClient.getChainId();
|
|
2359
2501
|
const DataPortabilityPermissionsAddress = (0, import_addresses.getContractAddress)(
|
|
@@ -2368,7 +2510,16 @@ class PermissionsController extends import_base.BaseController {
|
|
|
2368
2510
|
functionName: "revokePermissionWithSignature",
|
|
2369
2511
|
args: [typedData.message, formattedSignature],
|
|
2370
2512
|
account: this.context.walletClient?.account ?? this.context.userAddress,
|
|
2371
|
-
chain: this.context.walletClient?.chain ?? null
|
|
2513
|
+
chain: this.context.walletClient?.chain ?? null,
|
|
2514
|
+
...options && {
|
|
2515
|
+
gas: options.gas,
|
|
2516
|
+
nonce: options.nonce,
|
|
2517
|
+
// Use EIP-1559 gas pricing if available, otherwise legacy
|
|
2518
|
+
...options.maxFeePerGas || options.maxPriorityFeePerGas ? {
|
|
2519
|
+
maxFeePerGas: options.maxFeePerGas,
|
|
2520
|
+
maxPriorityFeePerGas: options.maxPriorityFeePerGas
|
|
2521
|
+
} : options.gasPrice ? { gasPrice: options.gasPrice } : {}
|
|
2522
|
+
}
|
|
2372
2523
|
});
|
|
2373
2524
|
return txHash;
|
|
2374
2525
|
}
|
|
@@ -2379,7 +2530,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
2379
2530
|
* @param signature - The cryptographic signature authorizing the untrust
|
|
2380
2531
|
* @returns Promise resolving to the transaction hash
|
|
2381
2532
|
*/
|
|
2382
|
-
async submitSignedUntrustTransaction(typedData, signature) {
|
|
2533
|
+
async submitSignedUntrustTransaction(typedData, signature, options) {
|
|
2383
2534
|
this.assertWallet();
|
|
2384
2535
|
const chainId = await this.context.walletClient.getChainId();
|
|
2385
2536
|
const DataPortabilityServersAddress = (0, import_addresses.getContractAddress)(
|
|
@@ -2398,7 +2549,16 @@ class PermissionsController extends import_base.BaseController {
|
|
|
2398
2549
|
functionName: "untrustServerWithSignature",
|
|
2399
2550
|
args: [contractMessage, formattedSignature],
|
|
2400
2551
|
account: this.context.walletClient?.account ?? this.context.userAddress,
|
|
2401
|
-
chain: this.context.walletClient?.chain ?? null
|
|
2552
|
+
chain: this.context.walletClient?.chain ?? null,
|
|
2553
|
+
...options && {
|
|
2554
|
+
gas: options.gas,
|
|
2555
|
+
nonce: options.nonce,
|
|
2556
|
+
// Use EIP-1559 gas pricing if available, otherwise legacy
|
|
2557
|
+
...options.maxFeePerGas || options.maxPriorityFeePerGas ? {
|
|
2558
|
+
maxFeePerGas: options.maxFeePerGas,
|
|
2559
|
+
maxPriorityFeePerGas: options.maxPriorityFeePerGas
|
|
2560
|
+
} : options.gasPrice ? { gasPrice: options.gasPrice } : {}
|
|
2561
|
+
}
|
|
2402
2562
|
});
|
|
2403
2563
|
return txHash;
|
|
2404
2564
|
}
|
|
@@ -2411,6 +2571,9 @@ class PermissionsController extends import_base.BaseController {
|
|
|
2411
2571
|
* A grantee is an entity (like an application) that can receive data permissions
|
|
2412
2572
|
* from users. Once registered, users can grant the grantee access to their data.
|
|
2413
2573
|
*
|
|
2574
|
+
* This method supports gasless transactions via relayer when configured.
|
|
2575
|
+
* If no relayer is available, it falls back to direct wallet transactions.
|
|
2576
|
+
*
|
|
2414
2577
|
* @param params - Parameters for registering the grantee
|
|
2415
2578
|
* @param params.owner - The Ethereum address that will own this grantee registration
|
|
2416
2579
|
* @param params.granteeAddress - The Ethereum address of the grantee (application)
|
|
@@ -2419,7 +2582,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
2419
2582
|
* @returns Promise resolving to the transaction hash
|
|
2420
2583
|
* @throws {BlockchainError} When the grantee registration transaction fails
|
|
2421
2584
|
* @throws {UserRejectedRequestError} When user rejects the transaction
|
|
2422
|
-
* @throws {
|
|
2585
|
+
* @throws {RelayerError} When gasless transaction submission fails
|
|
2423
2586
|
*
|
|
2424
2587
|
* @example
|
|
2425
2588
|
* ```typescript
|
|
@@ -2432,44 +2595,87 @@ class PermissionsController extends import_base.BaseController {
|
|
|
2432
2595
|
* ```
|
|
2433
2596
|
*/
|
|
2434
2597
|
async submitRegisterGrantee(params, options) {
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
account,
|
|
2451
|
-
chain: this.context.walletClient?.chain ?? null,
|
|
2452
|
-
...options?.gasLimit && { gas: options.gasLimit },
|
|
2453
|
-
...options?.nonce && { nonce: options.nonce },
|
|
2454
|
-
// Use EIP-1559 if available, otherwise fall back to legacy gasPrice
|
|
2455
|
-
...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
|
|
2456
|
-
...options.maxFeePerGas && { maxFeePerGas: options.maxFeePerGas },
|
|
2457
|
-
...options.maxPriorityFeePerGas && {
|
|
2458
|
-
maxPriorityFeePerGas: options.maxPriorityFeePerGas
|
|
2598
|
+
try {
|
|
2599
|
+
let hash;
|
|
2600
|
+
if (this.context.relayer) {
|
|
2601
|
+
const request = {
|
|
2602
|
+
type: "direct",
|
|
2603
|
+
operation: "submitRegisterGrantee",
|
|
2604
|
+
params: {
|
|
2605
|
+
owner: params.owner,
|
|
2606
|
+
granteeAddress: params.granteeAddress,
|
|
2607
|
+
publicKey: params.publicKey
|
|
2608
|
+
}
|
|
2609
|
+
};
|
|
2610
|
+
const response = await this.context.relayer(request);
|
|
2611
|
+
if (response.type === "error") {
|
|
2612
|
+
throw new import_errors.RelayerError(response.error);
|
|
2459
2613
|
}
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2614
|
+
if (response.type === "submitted") {
|
|
2615
|
+
hash = response.hash;
|
|
2616
|
+
} else if (response.type === "direct") {
|
|
2617
|
+
const result = response.result;
|
|
2618
|
+
hash = result.transactionHash;
|
|
2619
|
+
} else {
|
|
2620
|
+
throw new Error("Unexpected response type from relayer");
|
|
2621
|
+
}
|
|
2622
|
+
} else {
|
|
2623
|
+
this.assertWallet();
|
|
2624
|
+
const chainId = await this.context.walletClient.getChainId();
|
|
2625
|
+
const DataPortabilityGranteesAddress = (0, import_addresses.getContractAddress)(
|
|
2626
|
+
chainId,
|
|
2627
|
+
"DataPortabilityGrantees"
|
|
2628
|
+
);
|
|
2629
|
+
const DataPortabilityGranteesAbi = (0, import_abi.getAbi)("DataPortabilityGrantees");
|
|
2630
|
+
const ownerAddress = (0, import_viem.getAddress)(params.owner);
|
|
2631
|
+
const granteeAddress = (0, import_viem.getAddress)(params.granteeAddress);
|
|
2632
|
+
const account2 = this.context.walletClient?.account ?? this.context.userAddress;
|
|
2633
|
+
hash = await this.context.walletClient.writeContract({
|
|
2634
|
+
address: DataPortabilityGranteesAddress,
|
|
2635
|
+
abi: DataPortabilityGranteesAbi,
|
|
2636
|
+
functionName: "registerGrantee",
|
|
2637
|
+
args: [ownerAddress, granteeAddress, params.publicKey],
|
|
2638
|
+
account: account2,
|
|
2639
|
+
chain: this.context.walletClient?.chain ?? null,
|
|
2640
|
+
...this.spreadTransactionOptions(options)
|
|
2641
|
+
});
|
|
2642
|
+
}
|
|
2643
|
+
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
2644
|
+
const { tx } = await import("../utils/transactionHelpers");
|
|
2645
|
+
return tx({
|
|
2646
|
+
hash,
|
|
2647
|
+
from: typeof account === "string" ? account : account.address,
|
|
2648
|
+
contract: "DataPortabilityGrantees",
|
|
2649
|
+
fn: "registerGrantee"
|
|
2650
|
+
});
|
|
2651
|
+
} catch (error) {
|
|
2652
|
+
if (error instanceof Error) {
|
|
2653
|
+
if (error instanceof import_errors.RelayerError || error instanceof import_errors.UserRejectedRequestError || error instanceof import_errors.SerializationError || error instanceof import_errors.SignatureError || error instanceof import_errors.BlockchainError) {
|
|
2654
|
+
throw error;
|
|
2655
|
+
}
|
|
2656
|
+
if (error.name === "ContractFunctionExecutionError") {
|
|
2657
|
+
throw new import_errors.BlockchainError(
|
|
2658
|
+
`Grantee registration failed: ${error.message}`,
|
|
2659
|
+
error
|
|
2660
|
+
);
|
|
2661
|
+
}
|
|
2662
|
+
if (error.name === "UserRejectedRequestError") {
|
|
2663
|
+
throw new import_errors.UserRejectedRequestError(
|
|
2664
|
+
"User rejected the grantee registration transaction"
|
|
2665
|
+
);
|
|
2666
|
+
}
|
|
2667
|
+
throw new import_errors.BlockchainError(
|
|
2668
|
+
`Failed to register grantee: ${error.message}`,
|
|
2669
|
+
error
|
|
2670
|
+
);
|
|
2671
|
+
}
|
|
2672
|
+
throw new import_errors.BlockchainError(`Failed to register grantee: ${String(error)}`);
|
|
2673
|
+
}
|
|
2469
2674
|
}
|
|
2470
2675
|
// TODO: When DataPortabilityGrantees contract adds registerGranteeWithSignature function,
|
|
2471
2676
|
// implement submitRegisterGranteeWithSignature and submitSignedRegisterGrantee methods
|
|
2472
|
-
// to support gasless transactions via relayer
|
|
2677
|
+
// to support EIP-712 signed gasless transactions via relayer.
|
|
2678
|
+
// Current implementation above supports direct gasless transactions (relayer pays gas directly).
|
|
2473
2679
|
/**
|
|
2474
2680
|
* Retrieves all registered grantees from the DataPortabilityGrantees contract.
|
|
2475
2681
|
*
|
|
@@ -2517,27 +2723,52 @@ class PermissionsController extends import_base.BaseController {
|
|
|
2517
2723
|
const total = Number(totalCount);
|
|
2518
2724
|
const limit = options.limit ?? 50;
|
|
2519
2725
|
const offset = options.offset ?? 0;
|
|
2520
|
-
const
|
|
2521
|
-
const
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2726
|
+
const includePermissions = options.includePermissions ?? true;
|
|
2727
|
+
const startId = total - offset;
|
|
2728
|
+
const endId = Math.max(startId - limit + 1, 1);
|
|
2729
|
+
const granteeIds = Array.from(
|
|
2730
|
+
{ length: startId - endId + 1 },
|
|
2731
|
+
(_, i) => startId - i
|
|
2732
|
+
// Generate IDs in descending order
|
|
2733
|
+
);
|
|
2734
|
+
let grantees;
|
|
2735
|
+
if (includePermissions) {
|
|
2736
|
+
const granteePromises = granteeIds.map(
|
|
2737
|
+
(granteeId) => this.getGranteeById(granteeId)
|
|
2738
|
+
);
|
|
2739
|
+
const granteeResults = await Promise.all(granteePromises);
|
|
2740
|
+
grantees = granteeResults.filter(
|
|
2741
|
+
(grantee) => grantee !== null
|
|
2742
|
+
);
|
|
2743
|
+
} else {
|
|
2744
|
+
const granteeInfoPromises = granteeIds.map(
|
|
2745
|
+
async (granteeId) => {
|
|
2746
|
+
try {
|
|
2747
|
+
const granteeInfo = await this.context.publicClient.readContract({
|
|
2748
|
+
address: DataPortabilityGranteesAddress,
|
|
2749
|
+
abi: DataPortabilityGranteesAbi,
|
|
2750
|
+
functionName: "granteesV2",
|
|
2751
|
+
args: [BigInt(granteeId)]
|
|
2752
|
+
});
|
|
2753
|
+
const grantee = {
|
|
2754
|
+
id: granteeId,
|
|
2755
|
+
owner: granteeInfo.owner,
|
|
2756
|
+
address: granteeInfo.granteeAddress,
|
|
2757
|
+
publicKey: granteeInfo.publicKey,
|
|
2758
|
+
permissionIds: []
|
|
2759
|
+
// TypeScript infers number[] from Grantee type
|
|
2760
|
+
};
|
|
2761
|
+
return grantee;
|
|
2762
|
+
} catch (error) {
|
|
2763
|
+
console.warn(`Failed to fetch grantee ${granteeId}:`, error);
|
|
2764
|
+
return null;
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2767
|
+
);
|
|
2768
|
+
const granteeInfoResults = await Promise.all(granteeInfoPromises);
|
|
2769
|
+
grantees = granteeInfoResults.filter(
|
|
2770
|
+
(grantee) => grantee !== null
|
|
2771
|
+
);
|
|
2541
2772
|
}
|
|
2542
2773
|
return {
|
|
2543
2774
|
grantees,
|
|
@@ -2548,15 +2779,16 @@ class PermissionsController extends import_base.BaseController {
|
|
|
2548
2779
|
};
|
|
2549
2780
|
}
|
|
2550
2781
|
/**
|
|
2551
|
-
* Retrieves a specific grantee by their Ethereum address
|
|
2782
|
+
* Retrieves a specific grantee by their Ethereum wallet address.
|
|
2552
2783
|
*
|
|
2784
|
+
* @remarks
|
|
2553
2785
|
* Looks up a registered grantee (application) using their Ethereum address
|
|
2554
|
-
* and returns their complete registration information including permissions.
|
|
2786
|
+
* and returns their complete registration information including all associated permissions.
|
|
2555
2787
|
*
|
|
2556
|
-
*
|
|
2557
|
-
*
|
|
2558
|
-
* @
|
|
2559
|
-
* @
|
|
2788
|
+
* Returns `null` if the address is not registered as a grantee or if an error occurs.
|
|
2789
|
+
*
|
|
2790
|
+
* @param granteeAddress - Ethereum wallet address of the grantee to query
|
|
2791
|
+
* @returns Grantee information including ID, addresses, public key, and permission IDs, or `null` if not found
|
|
2560
2792
|
*
|
|
2561
2793
|
* @example
|
|
2562
2794
|
* ```typescript
|
|
@@ -2581,40 +2813,32 @@ class PermissionsController extends import_base.BaseController {
|
|
|
2581
2813
|
);
|
|
2582
2814
|
const DataPortabilityGranteesAbi = (0, import_abi.getAbi)("DataPortabilityGrantees");
|
|
2583
2815
|
try {
|
|
2584
|
-
const granteeInfo = await this.context.publicClient.readContract({
|
|
2585
|
-
address: DataPortabilityGranteesAddress,
|
|
2586
|
-
abi: DataPortabilityGranteesAbi,
|
|
2587
|
-
functionName: "granteeByAddress",
|
|
2588
|
-
args: [granteeAddress]
|
|
2589
|
-
});
|
|
2590
2816
|
const granteeId = await this.context.publicClient.readContract({
|
|
2591
2817
|
address: DataPortabilityGranteesAddress,
|
|
2592
2818
|
abi: DataPortabilityGranteesAbi,
|
|
2593
2819
|
functionName: "granteeAddressToId",
|
|
2594
2820
|
args: [granteeAddress]
|
|
2595
2821
|
});
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
publicKey: granteeInfo.publicKey,
|
|
2601
|
-
permissionIds: granteeInfo.permissionIds.map((id) => Number(id))
|
|
2602
|
-
};
|
|
2822
|
+
if (granteeId === 0n) {
|
|
2823
|
+
return null;
|
|
2824
|
+
}
|
|
2825
|
+
return await this.getGranteeById(Number(granteeId));
|
|
2603
2826
|
} catch (error) {
|
|
2604
2827
|
console.warn(`Failed to fetch grantee ${granteeAddress}:`, error);
|
|
2605
2828
|
return null;
|
|
2606
2829
|
}
|
|
2607
2830
|
}
|
|
2608
2831
|
/**
|
|
2609
|
-
* Retrieves a specific grantee by their unique ID
|
|
2832
|
+
* Retrieves a specific grantee by their unique ID.
|
|
2610
2833
|
*
|
|
2834
|
+
* @remarks
|
|
2611
2835
|
* Looks up a registered grantee (application) using their numeric ID assigned during
|
|
2612
|
-
* registration and returns their complete information including permissions.
|
|
2836
|
+
* registration and returns their complete information including all associated permissions.
|
|
2613
2837
|
*
|
|
2614
|
-
*
|
|
2615
|
-
*
|
|
2616
|
-
* @
|
|
2617
|
-
* @
|
|
2838
|
+
* Returns `null` if the grantee is not found or if an error occurs during fetching.
|
|
2839
|
+
*
|
|
2840
|
+
* @param granteeId - Unique numeric ID of the grantee (1-indexed)
|
|
2841
|
+
* @returns Grantee information including ID, addresses, public key, and permission IDs, or `null` if not found
|
|
2618
2842
|
*
|
|
2619
2843
|
* @example
|
|
2620
2844
|
* ```typescript
|
|
@@ -2622,7 +2846,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
2622
2846
|
*
|
|
2623
2847
|
* if (grantee) {
|
|
2624
2848
|
* console.log(`Grantee ID: ${grantee.id}`);
|
|
2625
|
-
* console.log(`Address: ${grantee.
|
|
2849
|
+
* console.log(`Address: ${grantee.address}`);
|
|
2626
2850
|
* console.log(`Owner: ${grantee.owner}`);
|
|
2627
2851
|
* console.log(`Total permissions: ${grantee.permissionIds.length}`);
|
|
2628
2852
|
* } else {
|
|
@@ -2638,18 +2862,23 @@ class PermissionsController extends import_base.BaseController {
|
|
|
2638
2862
|
);
|
|
2639
2863
|
const DataPortabilityGranteesAbi = (0, import_abi.getAbi)("DataPortabilityGrantees");
|
|
2640
2864
|
try {
|
|
2641
|
-
const
|
|
2865
|
+
const granteeInfoResult = await this.context.publicClient.readContract({
|
|
2642
2866
|
address: DataPortabilityGranteesAddress,
|
|
2643
2867
|
abi: DataPortabilityGranteesAbi,
|
|
2644
|
-
functionName: "
|
|
2868
|
+
functionName: "granteesV2",
|
|
2645
2869
|
args: [BigInt(granteeId)]
|
|
2646
2870
|
});
|
|
2871
|
+
const granteeInfo = granteeInfoResult;
|
|
2872
|
+
const allPermissionIdsResult = await this.getGranteePermissionsPaginated(
|
|
2873
|
+
BigInt(granteeId)
|
|
2874
|
+
);
|
|
2875
|
+
const allPermissionIds = allPermissionIdsResult;
|
|
2647
2876
|
return {
|
|
2648
2877
|
id: granteeId,
|
|
2649
2878
|
owner: granteeInfo.owner,
|
|
2650
2879
|
address: granteeInfo.granteeAddress,
|
|
2651
2880
|
publicKey: granteeInfo.publicKey,
|
|
2652
|
-
permissionIds:
|
|
2881
|
+
permissionIds: allPermissionIds.map((id) => Number(id))
|
|
2653
2882
|
};
|
|
2654
2883
|
} catch (error) {
|
|
2655
2884
|
console.warn(`Failed to fetch grantee ${granteeId}:`, error);
|
|
@@ -3046,6 +3275,31 @@ class PermissionsController extends import_base.BaseController {
|
|
|
3046
3275
|
);
|
|
3047
3276
|
}
|
|
3048
3277
|
}
|
|
3278
|
+
/**
|
|
3279
|
+
* Retrieves detailed grant file data from IPFS or HTTP storage.
|
|
3280
|
+
*
|
|
3281
|
+
* @remarks
|
|
3282
|
+
* This method automatically uses the SDK's configured downloadRelayer to bypass CORS restrictions.
|
|
3283
|
+
* Use this instead of importing the standalone `retrieveGrantFile` utility.
|
|
3284
|
+
*
|
|
3285
|
+
* @param grantUrl - The grant file URL (from OnChainPermissionGrant.grantUrl)
|
|
3286
|
+
* @returns Promise resolving to the complete grant file with operation details
|
|
3287
|
+
* @throws {NetworkError} When all retrieval attempts fail
|
|
3288
|
+
* @example
|
|
3289
|
+
* ```typescript
|
|
3290
|
+
* const grants = await vana.permissions.getUserPermissionGrantsOnChain();
|
|
3291
|
+
* const grantFile = await vana.permissions.retrieveGrantFile(grants[0].grantUrl);
|
|
3292
|
+
* console.log(`Operation: ${grantFile.operation}`);
|
|
3293
|
+
* ```
|
|
3294
|
+
*/
|
|
3295
|
+
async retrieveGrantFile(grantUrl) {
|
|
3296
|
+
const { retrieveGrantFile: retrieveGrantFileUtil } = await import("../utils/grantFiles");
|
|
3297
|
+
return retrieveGrantFileUtil(
|
|
3298
|
+
grantUrl,
|
|
3299
|
+
void 0,
|
|
3300
|
+
this.context.downloadRelayer
|
|
3301
|
+
);
|
|
3302
|
+
}
|
|
3049
3303
|
/**
|
|
3050
3304
|
* Get all permissions for a specific file (alias for getFilePermissionIds)
|
|
3051
3305
|
*
|
|
@@ -3071,26 +3325,34 @@ class PermissionsController extends import_base.BaseController {
|
|
|
3071
3325
|
// DATA PORTABILITY GRANTEES HELPER METHODS
|
|
3072
3326
|
// ===========================
|
|
3073
3327
|
/**
|
|
3074
|
-
*
|
|
3328
|
+
* Retrieves detailed grantee information including all associated permissions.
|
|
3329
|
+
*
|
|
3330
|
+
* @remarks
|
|
3331
|
+
* Returns grantee metadata and associated permission IDs. Uses the newer
|
|
3332
|
+
* paginated contract method internally for efficient permission fetching.
|
|
3075
3333
|
*
|
|
3076
|
-
* @param granteeId -
|
|
3077
|
-
* @returns
|
|
3334
|
+
* @param granteeId - Unique grantee identifier as bigint
|
|
3335
|
+
* @returns Grantee information containing owner address, grantee address, public key, and permission IDs
|
|
3336
|
+
* @throws {BlockchainError} When grantee ID is not found or contract read fails
|
|
3337
|
+
*
|
|
3338
|
+
* @example
|
|
3339
|
+
* ```typescript
|
|
3340
|
+
* const granteeInfo = await vana.permissions.getGranteeInfo(BigInt(1));
|
|
3341
|
+
* console.log(`Grantee ${granteeInfo.granteeAddress} has ${granteeInfo.permissionIds.length} permissions`);
|
|
3342
|
+
* ```
|
|
3078
3343
|
*/
|
|
3079
3344
|
async getGranteeInfo(granteeId) {
|
|
3080
3345
|
try {
|
|
3081
|
-
const
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
args: [granteeId]
|
|
3092
|
-
});
|
|
3093
|
-
return granteeInfo;
|
|
3346
|
+
const grantee = await this.getGranteeById(Number(granteeId));
|
|
3347
|
+
if (!grantee) {
|
|
3348
|
+
throw new Error("Grantee not found");
|
|
3349
|
+
}
|
|
3350
|
+
return {
|
|
3351
|
+
owner: grantee.owner,
|
|
3352
|
+
granteeAddress: grantee.address,
|
|
3353
|
+
publicKey: grantee.publicKey,
|
|
3354
|
+
permissionIds: grantee.permissionIds.map((id) => BigInt(id))
|
|
3355
|
+
};
|
|
3094
3356
|
} catch (error) {
|
|
3095
3357
|
throw new import_errors.BlockchainError(
|
|
3096
3358
|
`Failed to get grantee info: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
@@ -3099,10 +3361,21 @@ class PermissionsController extends import_base.BaseController {
|
|
|
3099
3361
|
}
|
|
3100
3362
|
}
|
|
3101
3363
|
/**
|
|
3102
|
-
*
|
|
3364
|
+
* Retrieves detailed grantee information by wallet address.
|
|
3365
|
+
*
|
|
3366
|
+
* @remarks
|
|
3367
|
+
* Looks up the grantee ID from the provided address, then fetches complete
|
|
3368
|
+
* grantee information including all associated permissions.
|
|
3369
|
+
*
|
|
3370
|
+
* @param granteeAddress - Ethereum wallet address of the grantee to query
|
|
3371
|
+
* @returns Grantee information containing owner address, grantee address, public key, and permission IDs
|
|
3372
|
+
* @throws {BlockchainError} When grantee address is not registered or contract read fails
|
|
3103
3373
|
*
|
|
3104
|
-
* @
|
|
3105
|
-
*
|
|
3374
|
+
* @example
|
|
3375
|
+
* ```typescript
|
|
3376
|
+
* const granteeInfo = await vana.permissions.getGranteeInfoByAddress("0x742d35Cc6634c0532925a3b844Bc9e8e1ee3b2De");
|
|
3377
|
+
* console.log(`Found grantee with ${granteeInfo.permissionIds.length} permissions`);
|
|
3378
|
+
* ```
|
|
3106
3379
|
*/
|
|
3107
3380
|
async getGranteeInfoByAddress(granteeAddress) {
|
|
3108
3381
|
try {
|
|
@@ -3112,13 +3385,26 @@ class PermissionsController extends import_base.BaseController {
|
|
|
3112
3385
|
"DataPortabilityGrantees"
|
|
3113
3386
|
);
|
|
3114
3387
|
const DataPortabilityGranteesAbi = (0, import_abi.getAbi)("DataPortabilityGrantees");
|
|
3115
|
-
const
|
|
3388
|
+
const granteeIdResult = await this.context.publicClient.readContract({
|
|
3116
3389
|
address: DataPortabilityGranteesAddress,
|
|
3117
3390
|
abi: DataPortabilityGranteesAbi,
|
|
3118
|
-
functionName: "
|
|
3391
|
+
functionName: "granteeAddressToId",
|
|
3119
3392
|
args: [granteeAddress]
|
|
3120
3393
|
});
|
|
3121
|
-
|
|
3394
|
+
const granteeId = granteeIdResult;
|
|
3395
|
+
if (granteeId === 0n) {
|
|
3396
|
+
throw new Error("Grantee not found");
|
|
3397
|
+
}
|
|
3398
|
+
const grantee = await this.getGranteeById(Number(granteeId));
|
|
3399
|
+
if (!grantee) {
|
|
3400
|
+
throw new Error("Grantee not found");
|
|
3401
|
+
}
|
|
3402
|
+
return {
|
|
3403
|
+
owner: grantee.owner,
|
|
3404
|
+
granteeAddress: grantee.address,
|
|
3405
|
+
publicKey: grantee.publicKey,
|
|
3406
|
+
permissionIds: grantee.permissionIds.map((id) => BigInt(id))
|
|
3407
|
+
};
|
|
3122
3408
|
} catch (error) {
|
|
3123
3409
|
throw new import_errors.BlockchainError(
|
|
3124
3410
|
`Failed to get grantee info by address: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
@@ -3182,6 +3468,117 @@ class PermissionsController extends import_base.BaseController {
|
|
|
3182
3468
|
);
|
|
3183
3469
|
}
|
|
3184
3470
|
}
|
|
3471
|
+
/**
|
|
3472
|
+
* Retrieves permission IDs for a specific grantee with flexible pagination.
|
|
3473
|
+
*
|
|
3474
|
+
* @remarks
|
|
3475
|
+
* **Pagination Behavior:**
|
|
3476
|
+
* Returns different types based on parameters:
|
|
3477
|
+
* - Without offset/limit: Returns `bigint[]` of all permissions using batched multicall
|
|
3478
|
+
* - With offset/limit: Returns paginated object with `permissionIds`, `totalCount`, and `hasMore`
|
|
3479
|
+
*
|
|
3480
|
+
* Uses gas-aware multicall for efficient batch fetching when retrieving all permissions.
|
|
3481
|
+
*
|
|
3482
|
+
* @param granteeId - Grantee ID to get permissions for
|
|
3483
|
+
* @param options - Optional pagination parameters
|
|
3484
|
+
* @param options.offset - Zero-based starting index for pagination. Defaults to 0 when fetching all permissions. Required for single-page requests.
|
|
3485
|
+
* @param options.limit - Maximum number of permission IDs to return per page. Defaults to 100 when fetching all permissions. Required for single-page requests.
|
|
3486
|
+
* @returns When called without options: Array of all permission IDs as `bigint[]`.
|
|
3487
|
+
* When called with offset and limit: Paginated result object containing `permissionIds` array,
|
|
3488
|
+
* `totalCount`, and `hasMore` boolean.
|
|
3489
|
+
* @throws {BlockchainError} When contract read operation fails
|
|
3490
|
+
*
|
|
3491
|
+
* @example
|
|
3492
|
+
* ```typescript
|
|
3493
|
+
* // Fetch all permissions (no pagination params)
|
|
3494
|
+
* const allPermissions = await vana.permissions.getGranteePermissionsPaginated(BigInt(1));
|
|
3495
|
+
* console.log(`Total permissions: ${allPermissions.length}`);
|
|
3496
|
+
*
|
|
3497
|
+
* // Fetch a specific page (with pagination params)
|
|
3498
|
+
* const page = await vana.permissions.getGranteePermissionsPaginated(BigInt(1), {
|
|
3499
|
+
* offset: BigInt(0),
|
|
3500
|
+
* limit: BigInt(100)
|
|
3501
|
+
* });
|
|
3502
|
+
* console.log(`Fetched ${page.permissionIds.length} permissions`);
|
|
3503
|
+
* console.log(`Total: ${page.totalCount}, Has more: ${page.hasMore}`);
|
|
3504
|
+
*
|
|
3505
|
+
* // Fetch next page
|
|
3506
|
+
* if (page.hasMore) {
|
|
3507
|
+
* const nextPage = await vana.permissions.getGranteePermissionsPaginated(BigInt(1), {
|
|
3508
|
+
* offset: BigInt(100),
|
|
3509
|
+
* limit: BigInt(100)
|
|
3510
|
+
* });
|
|
3511
|
+
* }
|
|
3512
|
+
* ```
|
|
3513
|
+
*/
|
|
3514
|
+
async getGranteePermissionsPaginated(granteeId, options) {
|
|
3515
|
+
try {
|
|
3516
|
+
const chainId = await this.context.publicClient.getChainId();
|
|
3517
|
+
const DataPortabilityGranteesAddress = (0, import_addresses.getContractAddress)(
|
|
3518
|
+
chainId,
|
|
3519
|
+
"DataPortabilityGrantees"
|
|
3520
|
+
);
|
|
3521
|
+
const DataPortabilityGranteesAbi = (0, import_abi.getAbi)("DataPortabilityGrantees");
|
|
3522
|
+
const fetchOnlyOnePage = options?.offset !== void 0 && options?.limit !== void 0;
|
|
3523
|
+
if (fetchOnlyOnePage) {
|
|
3524
|
+
const result = await this.context.publicClient.readContract({
|
|
3525
|
+
address: DataPortabilityGranteesAddress,
|
|
3526
|
+
abi: DataPortabilityGranteesAbi,
|
|
3527
|
+
functionName: "granteePermissionsPaginated",
|
|
3528
|
+
args: [granteeId, options.offset, options.limit]
|
|
3529
|
+
});
|
|
3530
|
+
const [permissionIds, totalCount2, hasMore] = result;
|
|
3531
|
+
return {
|
|
3532
|
+
permissionIds: [...permissionIds],
|
|
3533
|
+
totalCount: totalCount2,
|
|
3534
|
+
hasMore
|
|
3535
|
+
};
|
|
3536
|
+
}
|
|
3537
|
+
const countResult = await this.context.publicClient.readContract({
|
|
3538
|
+
address: DataPortabilityGranteesAddress,
|
|
3539
|
+
abi: DataPortabilityGranteesAbi,
|
|
3540
|
+
functionName: "granteePermissionsPaginated",
|
|
3541
|
+
args: [granteeId, BigInt(0), BigInt(1)]
|
|
3542
|
+
});
|
|
3543
|
+
const [, totalCount] = countResult;
|
|
3544
|
+
if (totalCount === BigInt(0)) {
|
|
3545
|
+
return [];
|
|
3546
|
+
}
|
|
3547
|
+
const batchSize = options?.limit ?? BigInt(100);
|
|
3548
|
+
const startOffset = options?.offset ?? BigInt(0);
|
|
3549
|
+
const endOffset = totalCount;
|
|
3550
|
+
const numBatches = Math.ceil(
|
|
3551
|
+
Number(endOffset - startOffset) / Number(batchSize)
|
|
3552
|
+
);
|
|
3553
|
+
const paginationCalls = Array.from({ length: numBatches }, (_, i) => ({
|
|
3554
|
+
address: DataPortabilityGranteesAddress,
|
|
3555
|
+
abi: DataPortabilityGranteesAbi,
|
|
3556
|
+
functionName: "granteePermissionsPaginated",
|
|
3557
|
+
args: [
|
|
3558
|
+
granteeId,
|
|
3559
|
+
startOffset + BigInt(i) * batchSize,
|
|
3560
|
+
batchSize
|
|
3561
|
+
]
|
|
3562
|
+
}));
|
|
3563
|
+
const results = await (0, import_multicall.gasAwareMulticall)(
|
|
3564
|
+
this.context.publicClient,
|
|
3565
|
+
{
|
|
3566
|
+
contracts: paginationCalls
|
|
3567
|
+
}
|
|
3568
|
+
);
|
|
3569
|
+
const allPermissionIds = [];
|
|
3570
|
+
for (const result of results) {
|
|
3571
|
+
const [permissionIds] = result;
|
|
3572
|
+
allPermissionIds.push(...permissionIds);
|
|
3573
|
+
}
|
|
3574
|
+
return allPermissionIds;
|
|
3575
|
+
} catch (error) {
|
|
3576
|
+
throw new import_errors.BlockchainError(
|
|
3577
|
+
`Failed to get grantee permissions: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
3578
|
+
error
|
|
3579
|
+
);
|
|
3580
|
+
}
|
|
3581
|
+
}
|
|
3185
3582
|
// ===== DataPortabilityServersImplementation Methods =====
|
|
3186
3583
|
/**
|
|
3187
3584
|
* Get all server IDs for a user
|
|
@@ -3395,7 +3792,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
3395
3792
|
args: [serverId, url],
|
|
3396
3793
|
chain: this.context.walletClient?.chain,
|
|
3397
3794
|
account,
|
|
3398
|
-
...options?.
|
|
3795
|
+
...options?.gas && { gas: options.gas },
|
|
3399
3796
|
...options?.nonce && { nonce: options.nonce },
|
|
3400
3797
|
// Use EIP-1559 if available, otherwise fall back to legacy gasPrice
|
|
3401
3798
|
...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
|
|
@@ -3601,7 +3998,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
3601
3998
|
* @throws {BlockchainError} When permission addition fails
|
|
3602
3999
|
* @throws {NetworkError} When network communication fails
|
|
3603
4000
|
*/
|
|
3604
|
-
async submitSignedAddPermission(typedData, signature) {
|
|
4001
|
+
async submitSignedAddPermission(typedData, signature, options) {
|
|
3605
4002
|
this.assertWallet();
|
|
3606
4003
|
try {
|
|
3607
4004
|
let hash;
|
|
@@ -3616,7 +4013,9 @@ class PermissionsController extends import_base.BaseController {
|
|
|
3616
4013
|
if (response.type === "error") {
|
|
3617
4014
|
throw new import_errors.RelayerError(response.error);
|
|
3618
4015
|
}
|
|
3619
|
-
if (response.type === "
|
|
4016
|
+
if (response.type === "submitted") {
|
|
4017
|
+
hash = response.hash;
|
|
4018
|
+
} else if (response.type === "signed") {
|
|
3620
4019
|
hash = response.hash;
|
|
3621
4020
|
} else {
|
|
3622
4021
|
throw new Error("Unexpected response type from relayer");
|
|
@@ -3624,7 +4023,8 @@ class PermissionsController extends import_base.BaseController {
|
|
|
3624
4023
|
} else {
|
|
3625
4024
|
hash = await this.submitDirectAddPermissionTransaction(
|
|
3626
4025
|
typedData,
|
|
3627
|
-
signature
|
|
4026
|
+
signature,
|
|
4027
|
+
options
|
|
3628
4028
|
);
|
|
3629
4029
|
}
|
|
3630
4030
|
const account = this.context.walletClient?.account ?? this.context.userAddress;
|
|
@@ -3793,7 +4193,9 @@ class PermissionsController extends import_base.BaseController {
|
|
|
3793
4193
|
if (response.type === "error") {
|
|
3794
4194
|
throw new import_errors.RelayerError(response.error);
|
|
3795
4195
|
}
|
|
3796
|
-
if (response.type === "
|
|
4196
|
+
if (response.type === "submitted") {
|
|
4197
|
+
hash = response.hash;
|
|
4198
|
+
} else if (response.type === "signed") {
|
|
3797
4199
|
hash = response.hash;
|
|
3798
4200
|
} else {
|
|
3799
4201
|
throw new Error("Unexpected response type from relayer");
|
|
@@ -3855,7 +4257,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
3855
4257
|
args: [permissionId],
|
|
3856
4258
|
chain: this.context.walletClient?.chain,
|
|
3857
4259
|
account,
|
|
3858
|
-
...options?.
|
|
4260
|
+
...options?.gas && { gas: options.gas },
|
|
3859
4261
|
...options?.nonce && { nonce: options.nonce },
|
|
3860
4262
|
// Use EIP-1559 if available, otherwise fall back to legacy gasPrice
|
|
3861
4263
|
...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
|
|
@@ -3888,7 +4290,7 @@ class PermissionsController extends import_base.BaseController {
|
|
|
3888
4290
|
* @param signature - The cryptographic signature authorizing the transaction
|
|
3889
4291
|
* @returns Promise resolving to the transaction hash
|
|
3890
4292
|
*/
|
|
3891
|
-
async submitDirectAddPermissionTransaction(typedData, signature) {
|
|
4293
|
+
async submitDirectAddPermissionTransaction(typedData, signature, options) {
|
|
3892
4294
|
this.assertWallet();
|
|
3893
4295
|
const chainId = await this.context.walletClient.getChainId();
|
|
3894
4296
|
const DataPortabilityPermissionsAddress = (0, import_addresses.getContractAddress)(
|
|
@@ -3909,7 +4311,8 @@ class PermissionsController extends import_base.BaseController {
|
|
|
3909
4311
|
functionName: "addPermission",
|
|
3910
4312
|
args: [permissionInput, formattedSignature],
|
|
3911
4313
|
account: this.context.walletClient?.account ?? this.context.userAddress,
|
|
3912
|
-
chain: this.context.walletClient?.chain ?? null
|
|
4314
|
+
chain: this.context.walletClient?.chain ?? null,
|
|
4315
|
+
...this.spreadTransactionOptions(options)
|
|
3913
4316
|
});
|
|
3914
4317
|
return hash;
|
|
3915
4318
|
}
|
|
@@ -3944,22 +4347,11 @@ class PermissionsController extends import_base.BaseController {
|
|
|
3944
4347
|
address: DataPortabilityPermissionsAddress,
|
|
3945
4348
|
abi: DataPortabilityPermissionsAbi,
|
|
3946
4349
|
functionName: "addServerFilesAndPermissions",
|
|
3947
|
-
// @ts-expect-error - Viem's type inference for nested Permission[][] arrays is incompatible with our Permission type
|
|
3948
4350
|
args: [serverFilesAndPermissionInput, formattedSignature],
|
|
3949
4351
|
account: this.context.walletClient?.account ?? this.context.userAddress,
|
|
3950
4352
|
chain: this.context.walletClient?.chain ?? null,
|
|
3951
|
-
...options?.gasLimit && { gas: options.gasLimit },
|
|
3952
|
-
...options?.nonce && { nonce: options.nonce },
|
|
3953
4353
|
...options?.value && { value: options.value },
|
|
3954
|
-
|
|
3955
|
-
...options?.maxFeePerGas || options?.maxPriorityFeePerGas ? {
|
|
3956
|
-
...options.maxFeePerGas && {
|
|
3957
|
-
maxFeePerGas: options.maxFeePerGas
|
|
3958
|
-
},
|
|
3959
|
-
...options.maxPriorityFeePerGas && {
|
|
3960
|
-
maxPriorityFeePerGas: options.maxPriorityFeePerGas
|
|
3961
|
-
}
|
|
3962
|
-
} : options?.gasPrice && { gasPrice: options.gasPrice }
|
|
4354
|
+
...this.spreadTransactionOptions(options)
|
|
3963
4355
|
});
|
|
3964
4356
|
return hash;
|
|
3965
4357
|
}
|