dovuofficial/guardian-php-sdk

一个用于与The Guardian交互的PHP SDK

v3.0.1 2024-09-26 15:36 UTC

README

基于Guardian策略的配置消费和管理。

Latest Version on Packagist Tests Total Downloads

安装

您可以通过composer安装此包

composer require dovuofficial/guardian-php-sdk

正在进行中的工作

这是我们第三次创建围绕The Guardian的SDK。目前我们不确定是否将创建一个新的存储库或只是简单地对此当前存储库进行版本控制。

目标是通过直接连接到Guardian API服务本身,真正从零开始设计PHP SDK。

在接下来的几周内,有多个项目需要继续工作,以实现非常精细但简单的SDK。

-[x] 最小化与guardian接口所需的方法 -[x] 使用进程/模板作为与guardian交互的机制

  • 系统使用方法的持续文档记录
  • 基于假设验证Guardian工作流程元素的架构
  • 更新主要测试以确保可以通过API读取信任链(可能的缓存问题)
  • 更新主要测试以确保策略的导入过程发生
  • 更新主要测试以使用“监听器”等待特定状态就绪
    • 确保此调用无缝集成到给定的“工作流程”操作中
  • 添加功能和测试套件以支持“测试网”测试,在干运行后,满足要求
    • 能够使用账户ID/密钥创建新的测试网用户
    • 分配角色
    • 确保此阶段的监听器功能(我们不知道IPFS/Hedera调用需要多长时间)
  • 更新GuardianActionTransaction以检查角色,作为详细模式。
  • 更新核心测试(Dryrun/Testnet)以确保从头开始创建“标准注册表”
    • 这里的用例是,如果我们部署新的Guardian基础设施,测试套件需要从头开始运行所有端到端任务。
  • (进行中)确保我们有坚实的测试,突出显示当前的Guardian挑战,特别是当涉及到可扩展性问题时,特别是在数据查询的N+1问题上

这些任务将在端到端原始流程之后添加

  • 修改核心工作流程以允许任何阶段的自定义架构
  • 为特定用例输出新的配置文件

这些都是已被推迟并归类为低优先级的任务

  • (已推迟)能够摄入任何guardian策略,然后动态推断所有标签、角色、操作顺序以及架构。

当前的战略方法

由于几乎没有关于如何在生产/规模设置中正确使用Guardian API的文档,我们需要了解如何迫使Guardian默认更符合RESTful原则。

简而言之,我们目前使用的方法是在策略的所有数据区域注入“filterBlocks”,这是我们希望查询的所有数据区域。这相当复杂,但简而言之,如果工作流程中有特定的块,我们希望像查询项目位置一样查询,我们可以在事先创建一个过滤器。

目前,Guardian中仍然存在许多N+1问题。这意味着,为了确保我们满意地进行生产,我们还需要进行一些工作,我们需要一个基础软件,该软件能够正确处理简单的事情。

这个版本的SDK在过去三年中经过深思熟虑/优化,我们打算使用这个系统。

使用SDK,请参阅测试。

该SDK结合了中介者和策略模式,能够处理与特定工作流程模板相关的配置。

对于使用一些配置消费此SDK的客户来说,这是预期的流程

  1. 设置初始上下文对象(这可以简化)
  2. 从一个文件名导入“GuardianWorkflowConfiguration”。
  3. 生成一个规范,该规范应导入到您的系统中。
  4. 规范中的元素将在处理工作流程的每个阶段时被使用。

创建具有提供策略的上下文对象的方式如下。

$this->sdk = new DovuGuardianAPI();
$this->sdk->setGuardianBaseUrl("https://:3000/api/v1/");

$context = PolicyContext::using($this->sdk)->for($policy_id);
$this->policy_workflow = PolicyWorkflow::context($context);

/**
 * Set up the workflow from configuration
 */
$configuration = $this->policy_workflow->getConfiguration();
$conf = GuardianWorkflowConfiguration::get('test_workflow'); // From the "/config" folder
$specification = $configuration->generateWorkflowSpecification($conf['workflow']);

规范是一个数组,包含所有需要传递到“GuardianActionTransaction”的硬性要求的元素,此外,还添加了一个“schema_specification”,允许系统在击中Guardian系统之前验证有效载荷。

    [
      0 => array:4 [▶
        "role" => Dovu\GuardianPhpSdk\Constants\GuardianRole {#93▶}
        "tag" => "create_ecological_project"
        "type" => Dovu\GuardianPhpSdk\Workflow\Constants\WorkflowTask {#710▶}
        "schema_specification" => array:13 [▶
          "title" => "ELV Scrapping for CO2 Emission Avoidance (AMS-III.BA & AMS-III.AJ)"
          "description" => "End-of-life vehicle project registration for the recovery and recycling of materials from e-waste, using a digitised form of UN CDM Methodology version 3.0"
          "type" => "object"
          "required" => array:12 [▶]
          "uuid" => array:4 [▶]
          "field0" => array:4 [▶]
          "field1" => array:4 [▶]
          "field2" => array:4 [▶]
          "field3" => array:4 [▶]
          "field4" => array:4 [▶]
          "field5" => array:4 [▶]
          "field6" => array:4 [▶]
          "field7" => array:4 [▶]
        ]
      ]
    ]

将添加更多验证,以便可以相应地检查每个元素的字段。

中介对象,允许消费元素

这可以存储在状态中,或者每次创建新事务时生成。

/**
 * Create mediator object.
 */
$mediator = GuardianActionMediator::with($this->policy_workflow);

使用工作流元素实时消费工作流。

现在,系统外部消费策略的责任在“守护者”之外。

如果我们考虑其工作方式的不同阶段,以下是一些示例。

/**
 * Stage one: create an ecological project (identity handled outside)
 */
$users = $this->dry_run_scenario->createUser(); // Returns a list of all users
$user = (object) end($users);
$this->dry_run_scenario->login($user->did);
$this->policy_workflow->assignRole(GuardianRole::SUPPLIER);

/**
 * Build an object for the particular action
 */
$send_ecological = (object) $specification[0];
$element = WorkflowElement::parse($send_ecological);
$project = json_decode($project, true); // See "ResearchElvClientGuardianTest"

$result = GuardianActionTransaction::with($mediator)
    ->setWorkflowElement($element)
    ->setPayload($project)
    ->run();

注意: "$project"可以是JSON字符串、数组/字典,我们最终将添加验证,以确保给定的有效载荷实时符合特定工作流程元素的预期。

在测试中或在工作过程中,您可以添加日志语句(这里使用ray)-- 超时/睡眠函数将改为状态监听功能。

ray('$send_ecological');
ray($result);

// TODO: Use the listener logic (This will increase based off of the current resource load on API)
sleep(2);

流的下一个阶段将是处理“项目”的批准

/**
 * Stage two: login as registry (handled outside workflow)
 */
$this->dry_run_scenario->login($admin->did);

$approve_ecological = (object) $specification[1];
$element = WorkflowElement::parse($approve_ecological);

// TODO: This would be the "plucker" (can we make this more dynamic?)
$result = GuardianActionTransaction::with($mediator)
    ->setWorkflowElement($element)
    ->setFilterValue($project['uuid'])
    ->setApprovalOption(ApprovalOption::APPROVE)
    ->run();

在这个下一个状态/阶段,原始的“供应商”现在可以创建一个与项目连接的站点。

/**
 * Stage three: login as supplier for site creation (handled outside workflow)
 */
$this->dry_run_scenario->login($user->did);

$create_site = (object) $specification[2];
$element = WorkflowElement::parse($create_site);

$site = json_decode($site, true);

$result = GuardianActionTransaction::with($mediator)
    ->setWorkflowElement($element)
    ->setPayload($site)
    ->run();

就像以前一样,登录的行政/注册人员现在可以批准该站点。

/**
 * Stage four: login as registry for site approval (handled outside workflow)
 */
$this->dry_run_scenario->login($admin->did);

$approve_site = (object) $specification[3];
$element = WorkflowElement::parse($approve_site);

$result = GuardianActionTransaction::with($mediator)
    ->setWorkflowElement($element)
    ->setApprovalOption(ApprovalOption::APPROVE)
    ->setFilterValue($site['uuid'])
    ->run();

因此,现在“供应商”可以在有证明某些影响活动的站点上发出索赔。

/**
 * Stage five: login as supplier for claim creation (handled outside workflow)
 */
$this->dry_run_scenario->login($user->did);

$create_claim = (object) $specification[4];
$element = WorkflowElement::parse($create_claim);

$claim = json_decode($claim, true);

$result = GuardianActionTransaction::with($mediator)
    ->setWorkflowElement($element)
    ->setPayload($claim)
    ->setFilterValue($site['uuid'])
    ->run();

最后,必须获得访问验证者、受信任的权威机构,它可以签署或批准某个索赔,然后发放令牌。

/**
 * Stage six: create a verifier user
 */

// Create verifier
$users = $this->dry_run_scenario->createUser(); // Returns a list of all users
$verifier = (object) end($users);

// Assign role
$this->dry_run_scenario->login($verifier->did);
$this->policy_workflow->assignRole(GuardianRole::VERIFIER);

/**
 * Stage seven: login as verifier for claim approval (handled outside workflow)
 */
$this->dry_run_scenario->login($verifier->did);

$approve_claim = (object) $specification[5];
$element = WorkflowElement::parse($approve_claim);

$result = GuardianActionTransaction::with($mediator)
    ->setWorkflowElement($element)
    ->setApprovalOption(ApprovalOption::APPROVE)
    ->setFilterValue($claim['uuid'])
    ->run();

从此时起,将生成信任链,它还将嵌入所有这些信息并发放数字信用。

工作流程和模板的影响。

此模板依赖于我们的特定“DOVU标准”,并传统上遵循IWA流程。

这种方法的好处是,任何工作流程配置都可以调整或创建,以便更接近特定集中式注册机构或其他实体的需求。

例如,对于Verra,期望验证者/VVB必须审查和批准项目或PDD,而不是注册机构本身--这是令牌的发放,它不依赖于持续的验证,而是外部行为者对项目本身的状态感到满意,并且他们愿意在项目验证后发放持续的信用。

因此,考虑到这一点,系统需要管理的只是在任何特定结构中使用任何配置的能力,在这些用例完全在守护者内部形成之后。在这些测试成功之后,可以使用相同的流程模板分支到任何一种方法(通过注入“n”层深的模式)以针对特定注册表。这些方法可以通过使用AI系统生成,并可以从注册表当局进一步验证其有效性。

理解GuardianActionTransaction对象。

GuardianActionTransaction对象专注于通过提供一个可配置为特定上下文或换句话说,是否需要将某物发布到“策略块”或需要批准“块”的单个构建器类,以确保处理守护者策略的最简单方式。

正在进行的工作将包括验证是否为特定的工作流操作提供了足够的信息,作为一个持续的任务,它需要更防御性地自动检查不良状态和输入(可能作为“冗长”模式)。

以下是构建器中每个单独方法的分解以及它们应该如何用于测试工作流程的每个部分。

基本对象

以下代码片段生成与任何工作流程元素连接的基本事务。

GuardianActionTransaction::with($mediator)->setWorkflowElement($element)

操作事务方法

使用setPayload方法将特定有效负载连接到事务,这将在将数据提交到工作流程中特定项/块时使用。

可以使用setFilterValue进行任何需要某种类型的筛选的操作,例如批准特定实体或提交身份,其中在其前面有许多实体,如将声明连接到站点的声明。

应仅在使用工作流中的实体批准/拒绝时使用setApprovalOption

run方法接收所有提供的信息并尝试将其作为守护者动作进行处理(待办事项:我们将添加验证以确保对于特定的动作,或已提交的元素,有效负载是有效的)。

信任链和令牌来源的审计

通过花园发行资产后,您可以使用Trustchain类返回所有可用于创建外部可视化的信息。查看创建某物的整个流程以及所有演员。

对于资产来源,在网络上有与资产关联的序列号,您可以匹配先前添加到策略实例的唯一标识符,例如“声明”模式中的uuid。

请参阅“TokenAuditTrail”测试以获取更多信息

它是如何工作的(低级)

由于我们开发的策略完全超出了任何现有文档的范围,因此这是工作流程的运作方式。

可以与系统交互的特定角色,对于DOVU模板,有“供应商”和“验证者”角色,超级用户/管理员/注册表也被使用。

目前,我们专注于开发一个干运行,以确保我们可以与Envision团队一起工作,突出创建基础API的所有潜在瓶颈,该API应该能够合理地扩展。

每个用户都必须在代码中分配一个角色,它看起来像这样

$users = $this->dry_run_scenario->createUser();
$user = (object) end($users);
$this->dry_run_scenario->login($user->did);
$this->policy_workflow->assignRole(GuardianRole::SUPPLIER);

在这种情况下,“供应商”现在可以向先前已发布的策略发送数据或文件

$project = json_decode($project, true);
$uuid = $project['uuid'];

$tag = "create_ecological_project";
$this->policy_workflow->sendDocumentToTag($tag, $project);

值得注意的是,每个策略都有可能是完全独特的,虽然团队专注于创建类似的模板以帮助缓解这个问题,但最终需要将其构建到SDK中,这意味着任何策略都可能有潜力被遍历,其中可以提取出需要将数据推送到的地方。

接下来,管理员/注册表(或可能是VVB角色)可以登录并筛选与方法论相关的所有项目/应用程序,审查后,可以使用以下代码进行批准。

$admin = $admin_did;

$this->dry_run_scenario->login($admin);

// This is stateful in API.
$this->policy_workflow->filterByTag("supplier_grid_filter", $uuid);
$supplier = $this->policy_workflow->dataByTagToDocumentBlock("supplier_grid");

$supplier->updateStatus(EntityStatus::APPROVED->value);
$option_tag = GuardianApprovalOption::APPROVE->value;

$supplier->assignTag($option_tag);

$tag = "approve_supplier_btn";
$this->policy_workflow->sendDataToTag($tag, $supplier->forDocumentSubmission());

当前 "filterByTag" 存在问题,包括需要失效的缓存以及许多添加到过滤器中的文档的 N+1 查询问题。

在此步骤之后,原始供应商可能开始提交网站,代表一个地理区域,与项目相关,因为原始项目已经获得了一个行为者/权威机构的批准,供应商现在拥有这种能力。

$site = json_decode($site, true);
$uuid = $site['uuid'];

// As the supplier user from before.
$this->dry_run_scenario->login($user->did);

$tag = "create_site_form";
$referred_doc = $supplier->chainDocumentAsReference($site);

$this->policy_workflow->sendDataToTag($tag, $referred_doc);

请注意,当前的函数 "chainDocumentAsReference" 是 Guardian 基础设施本身的某种高级特性,作为 API 系统理解正在发生什么的命令。您需要提供实际参考,该参考将回溯到您想要连接的先前块。对于许多开发者来说,这包括使用浏览器中的网络标签来完全理解并逆向工程整个过程。

下一阶段是让权威/登记机构批准为项目提供的网站(这与项目最初获得批准的过程类似)。

$this->dry_run_scenario->login($admin);

$this->policy_workflow->filterByTag("site_grid_owner_filter", $uuid);
$site = $this->policy_workflow->dataByTagToDocumentBlock("approve_sites_grid");

$site->updateStatus(EntityStatus::APPROVED->value);

$option_tag = GuardianApprovalOption::APPROVE->value;
$site->assignTag($option_tag);

$tag = "approve_site_button";

$this->policy_workflow->sendDataToTag($tag, $site->forDocumentSubmission());

从这一点开始,供应商现在可以提交一项声明,这指的是过程的 "dMRV" 或数据收集阶段,这并不是通过自我登记机构验证,而是通过第三方行为者,例如验证者或其他所有方都同意的证明。

$claim_doc = json_decode($claim, true);
$claim_uuid = $claim_doc['uuid'];

// As the supplier user from before.
$this->dry_run_scenario->login($user->did);

// Site uuid
$this->policy_workflow->filterByTag("site_grid_supplier_filter", $uuid);

$claim = $this->policy_workflow->dataByTagToDocumentBlock("sites_grid");

$tag = "create_claim_request_form";
$referred_doc = $claim->chainDocumentAsReference($claim_doc);

$this->policy_workflow->sendDataToTag($tag, $referred_doc);

对于最后阶段,可以创建一个验证者,所有之前通过 DOVU 系统引用的,并且可以分配给特定的政策,他们有验证数据和因此发行信用的能力。

// Create verifier
$users = $this->dry_run_scenario->createUser();
$verifier = (object) end($users);

// Assign role
$this->dry_run_scenario->login($verifier->did);
$this->policy_workflow->assignRole(GuardianRole::VERIFIER);

// This is stateful in API.
$this->policy_workflow->filterByTag("claim_request_verifier_filter", $claim_uuid);
$claim = $this->policy_workflow->dataByTagToDocumentBlock("claim_requests_grid(verifier)");

$claim->updateStatus(EntityStatus::APPROVED->value);
$option_tag = GuardianApprovalOption::APPROVE->value;
$claim->assignTag($option_tag);

$tag = "approve_claim_requests_btn";

// TODO: this approval isn't working
$this->policy_workflow->sendDataToTag($tag, $claim->forDocumentSubmission());

尽管所有这些代码片段似乎相对简单,但它们都经过了深思熟虑,有几个需要工作的添加,这是在 "ResearchElvClientGuardianTest" 测试案例中的工作进展。

V2 示例文档(已弃用)

此 SDK 允许您执行对 Dovu 的 Guardian API 中间件的 API 调用。使使用 Hedera Guardian 更加顺畅。

以下文档是当前的已弃用方法和流程,我们使用中间件 API 作为独立的服务,通过 HTTPS/REST 调用。

使用原始 SDK 的用法

$sdk = new Dovu\GuardianPhpSdk();

$sdk->setGuardianBaseUrl('https://:3001/api/');

$sdk->setHmacSecret('hmac_secret');

$sdk->addNotification(['slack' => 'https://hooks.slack.com/services/xxxxxxx']);

$response = $sdk->accounts->create('username','password');
$response = $sdk->accounts->login('username','password');

使用 Guardian SDK 辅助程序

$sdk = new Dovu\GuardianPhpSdk();

$sdk->setGuardianBaseUrl('https://:3001/api/');

$this->helper = new GuardianSDKHelper($sdk);

$registrant = $this->helper->createNewUser('username', 'secret');

$supplier_token = $registrant['data']['accessToken'];

$this->helper->setApiKey($supplier_token);

// Step two: Set the role for a user
$this->helper->setRole(GuardianRole::SUPPLIER);

// With a $project json 
$project = [ 'uuid' => \Ramsey\Uuid\Uuid::uuid4(), 'field1' => 'data' ];

$result = (object) $this->helper->createProject($project);

$project_uuid = json_decode($project, true)['uuid'];

/**
 * Waiting query for the registry to scan for the newly created project
 */
$waiting_query = EntityStateWaitingQuery::instance()
    ->query(StateQuery::PROJECTS)
    ->status(EntityStatus::WAITING)
    ->filter($project_uuid);

// Step four: approve the  through the standard registry
$result = (object) GuardianSDKHelper::actions(
    fn () => $this->helper->accessTokenForRegistry(),
    fn ($token) => $this->helper->setApiKey($token),
    fn () => $this->helper->stateEntityListener($waiting_query),
    fn ($query) => $this->helper->approveProject($query->id)
)();

V2 示例流程

运行以下测试以了解 Guardian SDK 辅助程序如何帮助简化对 Guardian 的消费。

 ./vendor/bin/pest --filter ElvGuardianPolicyIntegrationTest

该类主要是一系列装饰器辅助函数,但也有一些核心功能很有帮助。

具体来说

  • StateEntityListener
  • 动作

StateEntityListener 期望一个 EntityStateWaitingQuery,这将不断扫描 Guardian,以在动作发生后期望的状态。

因此,如果您创建了一个 "project" 文档,您可以通过扫描 "project" 的 "等待" 状态以供批准来自动化 Guardian 状态的扫描。由于 Guardian 有许多副作用,与常规 REST API 相比,最终确定状态可能较慢。

辅助程序的 动作 允许您将可组合单元逻辑链在一起,因此,如上所述的动作状态。

  • 检索登记机构的访问令牌
  • 设置 API 密钥
  • 创建一个等待查询以扫描期望的状态。
  • 使用查询的结果批准项目。

建议:由于 Guardian 平台是异步的,并且您无法确定数据何时可用。我们建议在文档中预先设置 UUID,这为您提供了一个唯一的值,确保您可以扫描唯一的实体(在 DOVU,我们的方法是在 field0 或 uuid 字段中设置此值)。

V1 示例流程(已弃用)

假设已经存在一个标准登记账户,该账户已发布了一个策略。

  • 创建新的登记账户
  • 创建新的验证者账户
  • 将新账户分配给策略
  • 使用登记账户登录
  • 提交申请
  • 使用标准登记账户登录
  • 批准申请
  • 使用登记账户登录
  • 提交生态项目
  • 使用标准登记账户登录
  • 批准生态项目
  • 使用登记账户登录
  • 提交新的MRV请求
  • 使用验证者账户登录
  • 批准MRV请求

MRV请求批准后,将自动铸造代表本生态项目中描述的碳的代币。

测试

composer test

变更日志

请参阅变更日志了解最近的变化信息。

贡献

请参阅贡献指南以获取详细信息。

安全漏洞

请查看我们的安全策略了解如何报告安全漏洞。

鸣谢

许可证

MIT许可证(MIT)。请参阅许可证文件以获取更多信息。