# @e4a/pg-wasm 中文文档

规范地址：https://npmcn.com/package/%40e4a/pg-wasm/

版本：0\.6\.10
npm 元数据更新时间：2026-10-20T11:37:00.932Z
中文译文更新时间：2026-11-13T03:16:03.696Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40e4a/pg-wasm
原文对照：https://npmcn.com/package/%40e4a/pg-wasm/?lang=original
项目主页：https://github.com/encryption4all/postguard/tree/main/pg-wasm#readme
源码仓库：https://github.com/encryption4all/postguard

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：1.6 MB，13 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：0 个
- 首次发布：2023-04-03T14:58:47.503Z
- 最新版本发布：2026-09-24T08:57:48.400Z
- 近 30 天下载量：2536（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：31（近 12 个月 17 个）

## 中文简介

用于浏览器的 PostGuard Web Assembly 绑定

## 安装

```sh
npm install @e4a/pg-wasm
```

也可以使用：`pnpm add @e4a/pg-wasm`、`yarn add @e4a/pg-wasm`、`bun add @e4a/pg-wasm`

## README

## {\\fn黑体\\fs22\\bord1\\shad0\\3ahbe\\4ah00\\fscx67\\fscy66\\2chffffff\\3ch808080}你这混蛋

大多数消费者想要 [`@e4a/pg-js`](https://www.npmjs.com/package/@e4a/pg-js) 而不是直接用这个包包来包装这些捆绑 API,以及 `@e4a/pg-wasm` 是它的依赖.

此软件包会在每集发布到 npm `pg-core` 发布时间 `pg-core`是因为 版本,没有自己的发行周期。 对于一个特定的变化 版本,已读 [`pg-core`更改日志](https://github.com/encryption4all/postguard/blob/main/pg-core/CHANGELOG.md) 相同的版本编号.

此软件包包含自动生成的WebAssembly 绑定以调用 来自 Javascript 或 Typescript 的 PostGuard Rust 库。 这个图书馆一直 配置为通过捆绑器在浏览器中运行 .

这个 `ReadableStream` 财务报告和审定财务报表 `WritableStream` 需要网络API. 最值得注意的是, `WritableStream` 在Firefox上不支持直到100版本,参见 [可写入结构](https://developer.mozilla.org/en-US/docs/Web/API/WritableStream)。 。 。 .

如果无法使用,请考虑使用多填充器,见 [网络流-聚合](https://www.npmjs.com/package/web-streams-polyfill)。 。 。 .

## 使用量

见 [实例 `postguard-js`](https://github.com/encryption4all/postguard-js/tree/main/examples) 工作实例.

### 获取密钥

从 PKG 获取密钥( 用于解密/ 签名) 是最简单的 Yivi 前端软件包和自定义 `session` 字段.

```javascript
// The URL of the PKG.
const PKG_URL = "...";

const KeySorts = {
  Encryption: "key",
  Signing: "sign/key",
};

export async function fetchKey(
  sort,
  keyRequest,
  timestamp = undefined,
  signingKeyRequest = undefined
) {
  const session = {
    url: PKG_URL,
    start: {
      url: (o) => `${o.url}/v2/request/start`,
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(keyRequest),
    },
    result: {
      url: (o, { sessionToken }) => `${o.url}/v2/request/jwt/${sessionToken}`,
      parseResponse: (r) => {
        return r
          .text()
          .then((jwt) =>
            fetch(
              `${PKG_URL}/v2/irma/${sort}${
                timestamp ? "/" + timestamp.toString() : ""
              }`,
              {
                method: sort === KeySorts.Encryption ? "GET" : "POST",
                headers: {
                  Authorization: `Bearer ${jwt}`,
                  "Content-Type": "application/json",
                },
                ...(signingKeyRequest && {
                  body: JSON.stringify({ ...signingKeyRequest }),
                }),
              }
            )
          )
          .then((r) => r.json())
          .then((json) => {
            if (json.status !== "DONE" || json.proofStatus !== "VALID")
              throw new Error("not done and valid");
            return sort === KeySorts.Encryption
              ? json.key
              : { pubSignKey: json.pubSignKey, privSignKey: json.privSignKey };
          })
          .catch((e) => console.log("error: ", e));
      },
    },
  };

  const yivi = new YiviCore({ debugging: false, session });
  yivi.use(YiviClient);
  yivi.use(YiviPopup);
  return yivi.start();
}
```

### 加密

```javascript
// Load the WASM module.
const { sealStream } = await import("@e4a/pg-wasm");

// Retrieve the public key from PKG API:
const resp = await fetch(`${url}/v2/parameters`);
const pk = await resp.json().then((r) => r.publicKey);

// We provide the policies which we want to use for encryption.
const policy = {
  Bob: {
    ts: Math.round(Date.now() / 1000),
    con: [{ t: "irma-demo.sidn-pbdf.email.email", v: "bob@example.com" }],
  },
};

// We provide the policies which we want to sign with.

// This policy is visible to everyone.
const pubSignId = [
  { t: "irma-demo.gemeente.personalData.fullname", v: "Alice" },
];

// This policy is only visible to recipients.
const privSignId = [{ t: "irma-demo.gemeente.personalData.bsn", v: "1234" }];

// We retrieve keys for these policies.
let { pubSignKey, privSignKey } = await fetchKey(
  KeySorts.Signing,
  { con: [...pubSignId, ...privSignId] },
  undefined,
  { pubSignId, privSignId }
);

const sealOptions = {
  policy,
  pubSignKey,
  privSignKey,
};

// The following call reads data from a `ReadableStream` and seals it into `WritableStream`.
// Make sure that only chunks of type `Uint8Array` are enqueued to `readable`.
await sealStream(pk, sealOptions, readable, writable);
```

### 解密

```javascript
// Load the WASM module.
const { StreamUnsealer } = await import("@e4a/pg-wasm");

// Retrieve to global verification key.
const vk = await fetch(`${PKG_URL}/v2/sign/parameters`)
  .then((r) => r.json())
  .then((j) => j.publicKey);

// Start reading from the ReadableStream. This will read
// the metadata up until the actual payload. The stream is still locked.
const unsealer = await StreamUnsealer.new(readable, vk);

// Retrieve the recipients (and their respective policies) from the header.
const recipients = unsealer.inspect_header();

// In this case it will yield:
// {
//  'Bob': {                                              // recipient identifier
//    ts: 1643634276,                                     // timestamp
//    con: [                                              // conjunction of attributes
//      { t: "irma-demo.sidn-pbdf.email.email", v: "" },  // type/value pairs
//    ],
//  },
// }

// The disclosed values have to match with the values used for encryption.
// Note that we do not include a timestamp here.
const keyRequest = {
  con: [{ t: "irma-demo.sidn-pbdf.email.email", v: "Bob" }],
};

const timestamp = recipients.get("Bob").ts;
const usk = await fetchKey(KeySorts.Encryption, keyRequest, timestamp);

// Unseal the contents, writing the plaintext to a `WritableStream`.
let sender = await unsealer.unseal("Bob", usk, writable);

// console.log(sender) will give the policy that was used to sign:
// {
//   "public": {
//     "ts": 1680531126,
//     "con": [
//       {
//         "t": "irma-demo.gemeente.personalData.fullname",
//         "v": "Alice"
//       }
//     ]
//   },
//   "private": {
//     "ts": 1680531130,
//     "con": [
//       {
//         "t": "irma-demo.gemeente.personalData.bsn",
//         "v": "1234"
//       }
//     ]
//   }
// }
```

### 加密 `Uint8Array`

加密和解密 `Uint8Array` 与上面的例子相似。 这个 WASM 模块也导出 `seal` 财务报告和审定财务报表 `Unsealer`,可用于此。 这个 函数 `seal` 返回一个新的 `Uint8Array`编辑 `Unsealer.unseal` 方法 返回数组 `[plain, policy]`时 `plain` 是一个 `Uint8Array` 包含 简写和 `policy` 是一个包含发送者的签名政策的对象.

### 使用网络工人

自兹 `ReadableStream` 财务报告和审定财务报表 `WritableStream` 为: [可转让](https://developer.mozilla.org/en-US/docs/Glossary/Transferable_objects), (中文(简体) ), 建议它进行封口和解除封口,例如, 在一个 [网络工作者](https://developer.mozilla.org/en-US/docs/Web/API/Worker)。 。 。 . [连接](https://github.com/GoogleChromeLabs/comlink) 可以成为有用的库 用于线条之间的通信.

## 常见问题

### @e4a/pg-wasm 是什么？

用于浏览器的 PostGuard Web Assembly 绑定

### 如何安装 @e4a/pg-wasm？

在项目目录运行 npm install @e4a/pg-wasm，或使用 pnpm add / yarn add / bun add。

### @e4a/pg-wasm 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @e4a/pg-wasm 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @e4a/pg-wasm 可以商用吗？

@e4a/pg-wasm 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @e4a/pg-wasm 的下载量有多少？

根据 npm 官方下载统计，@e4a/pg-wasm 在 2026/10/13 – 2026/11/11 这 30 天内被下载 2,536 次，日均约 85 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @e4a/pg-wasm 还在维护吗？

最新版本 0\.6\.10 发布于 2026/09/24（1 个月前）；至今共发布 31 个版本，其中过去 12 个月发布了 17 个；首次发布于 2023/04/03。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

