Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ exports[`API snapshots Api of AppleContract 1`] = `
"contractVersion": "?.?.?",
"methods": [
{
"description": "Apply queued internal requests Transaction updates the chain (submit). Allowed roles: CURATOR.",
"description": "Apply queued internal requests Transaction updates the chain (submit). Allowed roles: REQUEST_APPLIER.",
"dtoSchema": {
"properties": {
"domain": {
Expand Down Expand Up @@ -1873,7 +1873,7 @@ The key is generated by the caller and should be unique for each DTO. You can us
},
},
{
"description": "Apply queued internal requests Transaction updates the chain (submit). Allowed roles: CURATOR.",
"description": "Apply queued internal requests Transaction updates the chain (submit). Allowed roles: REQUEST_APPLIER.",
"dtoSchema": {
"properties": {
"domain": {
Expand Down Expand Up @@ -16541,7 +16541,7 @@ The key is generated by the caller and should be unique for each DTO. You can us
},
},
{
"description": "Apply queued internal requests Transaction updates the chain (submit). Allowed roles: CURATOR.",
"description": "Apply queued internal requests Transaction updates the chain (submit). Allowed roles: REQUEST_APPLIER.",
"dtoSchema": {
"properties": {
"domain": {
Expand Down
14 changes: 14 additions & 0 deletions chain-cli/chaincode-template/e2e/tokenOps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
ApplyRequestsDto,
CreateTokenClassDto,
FetchBalancesDto,
GetMyProfileDto,
GrantAllowanceDto,
MintTokenDto,
TokenAllowance,
Expand All @@ -25,6 +26,7 @@ import {
TokenInstance,
TokenInstanceKey,
TransferTokenDto,
UpdateUserRolesDto,
asValidUserRef,
createValidDTO,
createValidSubmitDTO
Expand Down Expand Up @@ -76,6 +78,18 @@ export async function requestMintTokensToUsers(
}

export async function applyRequests(client: AdminChainClients, delayMs = 2_500) {
const profileDto = new GetMyProfileDto();
profileDto.sign(client.pk.privateKey);
const profile = await client.pk.GetMyProfile(profileDto);
const roles = Array.isArray(profile.Data?.roles) ? (profile.Data.roles as string[]) : [];
if (!roles.includes("REQUEST_APPLIER")) {
const grantRoles = await createValidSubmitDTO(UpdateUserRolesDto, {
user: client.pk.identityKey,
roles: [...roles, "REQUEST_APPLIER"]
}).signed(client.pk.privateKey);
expect(await client.pk.submitTransaction("UpdateUserRoles", grantRoles)).toEqual(transactionSuccess());
}

await new Promise((resolve) => setTimeout(resolve, delayMs));
return client.assets.submitTransaction(
"ApplyRequests",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ exports[`AppleContract API should match snapshot 1`] = `
"contractVersion": "?.?.?",
"methods": [
{
"description": "Apply queued internal requests Transaction updates the chain (submit). Allowed roles: CURATOR.",
"description": "Apply queued internal requests Transaction updates the chain (submit). Allowed roles: REQUEST_APPLIER.",
"dtoSchema": {
"properties": {
"domain": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ The key is generated by the caller and should be unique for each DTO. You can us
},
},
{
"description": "Apply queued internal requests Transaction updates the chain (submit). Allowed roles: CURATOR.",
"description": "Apply queued internal requests Transaction updates the chain (submit). Allowed roles: REQUEST_APPLIER.",
"dtoSchema": {
"properties": {
"domain": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ The key is generated by the caller and should be unique for each DTO. You can us
},
},
{
"description": "Apply queued internal requests Transaction updates the chain (submit). Allowed roles: CURATOR.",
"description": "Apply queued internal requests Transaction updates the chain (submit). Allowed roles: REQUEST_APPLIER.",
"dtoSchema": {
"properties": {
"domain": {
Expand Down
5 changes: 3 additions & 2 deletions chaincode/src/contracts/GalaContract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ import { getApiMethod, getApiMethods } from "./GalaContractApi";
import { EVALUATE, GalaTransaction, SUBMIT, Submit } from "./GalaTransaction";
import { applySavedRequests, hasPendingApplyRequests } from "./GalaTransactionRequest";
import type { RequestMethodHandler } from "./GalaTransactionRequest";
import { requireCuratorAuth } from "./authorize";

export class BatchWriteLimitExceededError extends ValidationFailedError {
constructor(writesLimit: number) {
Expand All @@ -64,6 +63,8 @@ export class BatchPartialSuccessRequiredError extends ChainError {
}
}

const REQUEST_APPLIER_ROLE = "REQUEST_APPLIER";

export abstract class GalaContract extends Contract {
protected readonly requestMethodHandlers: Record<string, RequestMethodHandler> = {};

Expand Down Expand Up @@ -357,7 +358,7 @@ export abstract class GalaContract extends Contract {
in: ApplyRequestsDto,
out: { arrayOf: AppliedRequest },
description: "Apply queued internal requests",
...requireCuratorAuth
allowedRoles: [REQUEST_APPLIER_ROLE]
})
public async ApplyRequests(ctx: GalaChainContext, dto: ApplyRequestsDto): Promise<AppliedRequest[]> {
return applySavedRequests(ctx, this.getName(), dto, this.requestMethodHandlers);
Expand Down
21 changes: 18 additions & 3 deletions chaincode/src/contracts/GalaTransactionRequest.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ApplyRequestsDto, GalaChainResponseType } from "@gala-chain/api";
import {
ApplyRequestsDto,
GalaChainResponseType,
UpdateUserRolesDto,
createValidSubmitDTO
} from "@gala-chain/api";
import { TestChaincode, transactionSuccess } from "@gala-chain/test";
import { plainToInstance } from "class-transformer";

import TestGalaContract, { KVDto } from "../__test__/TestGalaContract";
import { PublicKeyContract } from "./PublicKeyContract";
import { createRegisteredUser } from "./authenticate.testutils.spec";

describe("ApplyRequests uniqueKey", () => {
it("echoes the queued request uniqueKey on each applied item", async () => {
const chaincode = new TestChaincode([TestGalaContract]);
const chaincode = new TestChaincode([TestGalaContract, PublicKeyContract]);
const applier = await createRegisteredUser(chaincode);
const grantRoles = await createValidSubmitDTO(UpdateUserRolesDto, {
user: applier.alias,
roles: ["REQUEST_APPLIER"]
}).signed(process.env.DEV_ADMIN_PRIVATE_KEY as string);
expect(await chaincode.invoke("PublicKeyContract:UpdateUserRoles", grantRoles)).toEqual(
transactionSuccess()
);

const requestDto = plainToInstance(KVDto, {
key: "queued-key",
Expand All @@ -33,7 +48,7 @@ describe("ApplyRequests uniqueKey", () => {
const applyDto = plainToInstance(ApplyRequestsDto, {
uniqueKey: "apply-uk-1",
minDelayMs: 0
}).signed(process.env.DEV_ADMIN_PRIVATE_KEY as string);
}).signed(applier.privateKey);
const applyResponse = await chaincode.invoke("TestGalaContract:ApplyRequests", applyDto.serialize());

expect(applyResponse).toEqual(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ The key is generated by the caller and should be unique for each DTO. You can us
},
},
{
"description": "Apply queued internal requests Transaction updates the chain (submit). Allowed roles: CURATOR.",
"description": "Apply queued internal requests Transaction updates the chain (submit). Allowed roles: REQUEST_APPLIER.",
"dtoSchema": {
"properties": {
"domain": {
Expand Down
Loading