Skip to content

Commit bb1d8d2

Browse files
committed
refactor(domains): create safe wallet organization
1 parent 798bcf7 commit bb1d8d2

File tree

4 files changed

+47
-63
lines changed

4 files changed

+47
-63
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/modules/domains/domains.service.ts

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,10 @@ import {
3232
MulticallTx,
3333
SetRoleDefinitionOptions,
3434
CreateOrganizationOptions,
35-
ReturnStep,
3635
CreateApplicationOptions,
3736
CreateRoleOptions,
3837
ChangeOrgOwnershipOptions,
3938
ChangeAppOwnershipOptions,
40-
ReturnStepWithRetryCheck,
4139
ChangeRoleOwnershipOptions,
4240
DeleteOrganizationOptions,
4341
DeleteApplicationOptions,
@@ -58,6 +56,7 @@ import { validateAddress } from '../../utils/address';
5856
import { UnregisteredResolverError } from '../../errors/unregistered-resolver.error';
5957
import { castToV2 } from './domains.types';
6058
import { getLogger } from '../../config/logger.config';
59+
import { GnosisSigner, ProviderType } from '../signer';
6160

6261
/**
6362
* Service responsible for handling the request to ENS, creating roles/organizations/applications namespaces.
@@ -190,6 +189,7 @@ export class DomainsService {
190189
/**
191190
* Create organization domain with given definition for given namespace.
192191
* Also includes creating subdomains for roles and applications. (roles.yourOrg.ewc, apps.yourOrg.ewc).
192+
* When organization is created in Gnosis interface it will be transfered to Safe wallet.
193193
*
194194
* ```typescript
195195
* domainsService.createOrganization({
@@ -210,19 +210,24 @@ export class DomainsService {
210210
namespace,
211211
data,
212212
returnSteps,
213-
}: CreateOrganizationOptions): Promise<ReturnStep[] | undefined> {
213+
}: CreateOrganizationOptions): Promise<MulticallTx | undefined> {
214214
const orgDomain = `${orgName}.${namespace}`;
215215
const rolesDomain = `${NamespaceType.Role}.${orgDomain}`;
216216
const appsDomain = `${NamespaceType.Application}.${orgDomain}`;
217217
if (!(await this.isOwner({ domain: namespace, user: this._owner }))) {
218218
throw new Error(ERROR_MESSAGES.NOT_AUTHORIZED_TO_CHANGE_DOMAIN);
219219
}
220-
const steps: ReturnStep[] = [
220+
const owner =
221+
this._signerService.providerType === ProviderType.Gnosis
222+
? (this._signerService.signer as GnosisSigner).safeInfo.safeAddress
223+
: this._owner;
224+
225+
const steps: MulticallTx = [
221226
{
222227
tx: this.createSubdomainTx({
223228
domain: namespace,
224229
nodeName: orgName,
225-
owner: this._owner,
230+
owner,
226231
}),
227232
info: 'Create organization subdomain',
228233
},
@@ -237,7 +242,7 @@ export class DomainsService {
237242
tx: this.createSubdomainTx({
238243
domain: orgDomain,
239244
nodeName: NamespaceType.Role,
240-
owner: this._owner,
245+
owner,
241246
}),
242247
info: 'Create roles subdomain for organization',
243248
},
@@ -251,7 +256,7 @@ export class DomainsService {
251256
tx: this.createSubdomainTx({
252257
domain: orgDomain,
253258
nodeName: NamespaceType.Application,
254-
owner: this._owner,
259+
owner,
255260
}),
256261
info: 'Create app subdomain for organization',
257262
},
@@ -264,7 +269,7 @@ export class DomainsService {
264269
].map((step) => ({
265270
...step,
266271
next: async () => {
267-
await this._signerService.send({ ...step.tx });
272+
return this._signerService.send({ ...step.tx });
268273
},
269274
}));
270275
if (returnSteps) {
@@ -300,10 +305,10 @@ export class DomainsService {
300305
namespace: domain,
301306
data,
302307
returnSteps,
303-
}: CreateApplicationOptions): Promise<ReturnStep[] | undefined> {
308+
}: CreateApplicationOptions): Promise<MulticallTx | undefined> {
304309
const appDomain = `${appName}.${domain}`;
305310
const from = await this.getOwner({ namespace: domain });
306-
const steps: ReturnStep[] = [
311+
const steps: MulticallTx = [
307312
{
308313
tx: this.createSubdomainTx({ domain, nodeName: appName, owner: from }),
309314
info: 'Set subdomain for application',
@@ -332,7 +337,7 @@ export class DomainsService {
332337
].map((step) => ({
333338
...step,
334339
next: async () => {
335-
await this._signerService.send(step.tx);
340+
return this._signerService.send(step.tx);
336341
},
337342
}));
338343
if (returnSteps) {
@@ -375,11 +380,11 @@ export class DomainsService {
375380
namespace,
376381
data,
377382
returnSteps,
378-
}: CreateRoleOptions): Promise<ReturnStep[] | undefined> {
383+
}: CreateRoleOptions): Promise<MulticallTx | undefined> {
379384
const dataV2 = castToV2(data);
380385
const newDomain = `${roleName}.${namespace}`;
381386
const from = await this.getOwner({ namespace });
382-
const steps: ReturnStep[] = [
387+
const steps: MulticallTx = [
383388
{
384389
tx: this.createSubdomainTx({
385390
domain: namespace,
@@ -398,7 +403,7 @@ export class DomainsService {
398403
].map((step) => ({
399404
...step,
400405
next: async () => {
401-
await this._signerService.send(step.tx);
406+
return this._signerService.send(step.tx);
402407
},
403408
}));
404409
if (returnSteps) {
@@ -519,9 +524,7 @@ export class DomainsService {
519524
namespace,
520525
newOwner,
521526
returnSteps,
522-
}: ChangeAppOwnershipOptions): Promise<
523-
ReturnStepWithRetryCheck[] | undefined
524-
> {
527+
}: ChangeAppOwnershipOptions): Promise<MulticallTx | undefined> {
525528
DomainsService.validateOwnerAddress(newOwner);
526529
const roles = await this.getRolesByNamespace({
527530
namespace,
@@ -552,22 +555,20 @@ export class DomainsService {
552555
);
553556
}
554557

555-
const steps: ReturnStepWithRetryCheck[] = changeOwnerNamespaces.map(
556-
(name) => {
557-
const tx = this.changeDomainOwnerTx({ newOwner, namespace: name });
558-
return {
559-
tx,
560-
next: async ({ retryCheck }: { retryCheck?: boolean } = {}) => {
561-
if (retryCheck) {
562-
const owner = await this.getOwner({ namespace: name });
563-
if (owner === newOwner) return;
564-
}
565-
return this._signerService.send(tx);
566-
},
567-
info: `Changing ownership of ${name}`,
568-
};
569-
}
570-
);
558+
const steps: MulticallTx = changeOwnerNamespaces.map((name) => {
559+
const tx = this.changeDomainOwnerTx({ newOwner, namespace: name });
560+
return {
561+
tx,
562+
next: async ({ retryCheck }: { retryCheck?: boolean } = {}) => {
563+
if (retryCheck) {
564+
const owner = await this.getOwner({ namespace: name });
565+
if (owner === newOwner) return;
566+
}
567+
return this._signerService.send(tx);
568+
},
569+
info: `Changing ownership of ${name}`,
570+
};
571+
});
571572

572573
if (returnSteps) {
573574
return steps;
@@ -626,9 +627,7 @@ export class DomainsService {
626627
async deleteOrganization({
627628
namespace,
628629
returnSteps = false,
629-
}: DeleteOrganizationOptions): Promise<
630-
ReturnStepWithRetryCheck[] | undefined
631-
> {
630+
}: DeleteOrganizationOptions): Promise<MulticallTx | undefined> {
632631
const apps = this._cacheClient
633632
? await this.getAppsOfOrg(namespace)
634633
: await this.getSubdomains({
@@ -710,9 +709,7 @@ export class DomainsService {
710709
async deleteApplication({
711710
namespace,
712711
returnSteps = false,
713-
}: DeleteApplicationOptions): Promise<
714-
ReturnStepWithRetryCheck[] | undefined
715-
> {
712+
}: DeleteApplicationOptions): Promise<MulticallTx | undefined> {
716713
const roles = this._cacheClient
717714
? await this._cacheClient.getApplicationRoles(namespace)
718715
: await this.getSubdomains({

src/modules/domains/domains.types.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
IRoleDefinition,
77
IRoleDefinitionV2,
88
} from '@energyweb/credential-governance';
9-
import { TransactionReceipt } from '@energyweb/ekc';
109
import { providers } from 'ethers';
1110

1211
export enum NamespaceType {
@@ -64,20 +63,6 @@ export function castToV2(
6463
}
6564
}
6665

67-
export interface ReturnStep {
68-
next: () => Promise<void>;
69-
tx: EncodedCall;
70-
info: string;
71-
}
72-
73-
export interface ReturnStepWithRetryCheck {
74-
next: (opt?: {
75-
retryCheck?: boolean;
76-
}) => Promise<TransactionReceipt | undefined>;
77-
tx: EncodedCall;
78-
info: string;
79-
}
80-
8166
export type MulticallTx = {
8267
tx: EncodedCall;
8368
next: (opts?: {
Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
import { providers } from 'ethers';
2-
import SafeAppSdk from '@gnosis.pm/safe-apps-sdk';
2+
import SafeAppSdk, { SafeInfo } from '@gnosis.pm/safe-apps-sdk';
33
import { SafeAppProvider } from '@gnosis.pm/safe-apps-provider';
4-
import { ProviderType } from './signer.types';
4+
import { ProviderType, SignerT } from './signer.types';
55
import { SignerService } from './signer.service';
66

77
/**
88
* @description Intended for use in Volta Gnosis web interface(https://volta.gnosis-safe.io/).
99
* Dapp should provide SafeAppSdk injected by Gnosis interface
1010
*/
1111
export const fromGnosis = async (safeAppSdk: SafeAppSdk) => {
12-
const gnosisProvider = new SafeAppProvider(
13-
await safeAppSdk.safe.getInfo(),
14-
safeAppSdk
15-
);
12+
const safeInfo = await safeAppSdk.safe.getInfo();
13+
const gnosisProvider = new SafeAppProvider(safeInfo, safeAppSdk);
1614
const provider = new providers.Web3Provider(gnosisProvider);
1715
const signerService = new SignerService(
18-
provider.getSigner(),
16+
Object.assign(provider.getSigner(), { safeInfo }),
1917
ProviderType.Gnosis
2018
);
2119
return signerService;
2220
};
21+
22+
export interface GnosisSigner extends SignerT {
23+
safeInfo: SafeInfo;
24+
}

0 commit comments

Comments
 (0)