@aigne/afs-ocap 1.12.0-beta.5
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/LICENSE.md +26 -0
- package/README.md +144 -0
- package/aup/accounts/default.json +64 -0
- package/aup/accounts/item.json +510 -0
- package/aup/assets/default.json +70 -0
- package/aup/assets/item.json +360 -0
- package/aup/bridges/_addr/blocks/item.json +168 -0
- package/aup/bridges/default.json +79 -0
- package/aup/bridges/item.json +868 -0
- package/aup/config/default.json +806 -0
- package/aup/default.json +387 -0
- package/aup/delegates/default.json +71 -0
- package/aup/delegates/item.json +241 -0
- package/aup/factories/default.json +78 -0
- package/aup/factories/item.json +310 -0
- package/aup/stakes/default.json +76 -0
- package/aup/stakes/item.json +374 -0
- package/aup/tokens/default.json +76 -0
- package/aup/tokens/item.json +384 -0
- package/aup/transactions/default.json +102 -0
- package/aup/transactions/item.json +286 -0
- package/aup/validators/default.json +57 -0
- package/aup/validators/item.json +99 -0
- package/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.cjs +11 -0
- package/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.mjs +10 -0
- package/dist/index.cjs +7 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.mjs +4 -0
- package/dist/method-colors.cjs +137 -0
- package/dist/method-colors.mjs +136 -0
- package/dist/method-colors.mjs.map +1 -0
- package/dist/provider.cjs +2490 -0
- package/dist/provider.d.cts +453 -0
- package/dist/provider.d.cts.map +1 -0
- package/dist/provider.d.mts +453 -0
- package/dist/provider.d.mts.map +1 -0
- package/dist/provider.mjs +2490 -0
- package/dist/provider.mjs.map +1 -0
- package/dist/remote-source.cjs +338 -0
- package/dist/remote-source.d.cts +62 -0
- package/dist/remote-source.d.cts.map +1 -0
- package/dist/remote-source.d.mts +62 -0
- package/dist/remote-source.d.mts.map +1 -0
- package/dist/remote-source.mjs +339 -0
- package/dist/remote-source.mjs.map +1 -0
- package/dist/source.d.cts +77 -0
- package/dist/source.d.cts.map +1 -0
- package/dist/source.d.mts +77 -0
- package/dist/source.d.mts.map +1 -0
- package/dist/types.d.cts +572 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +572 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/utils.cjs +581 -0
- package/dist/utils.mjs +557 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +61 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Proprietary License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2025 ArcBlock, Inc. All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
This software and associated documentation files (the "Software") are proprietary
|
|
6
|
+
and confidential. Unauthorized copying, modification, distribution, or use of
|
|
7
|
+
this Software, via any medium, is strictly prohibited.
|
|
8
|
+
|
|
9
|
+
The Software is provided for internal use only within ArcBlock, Inc. and its
|
|
10
|
+
authorized affiliates.
|
|
11
|
+
|
|
12
|
+
## No License Granted
|
|
13
|
+
|
|
14
|
+
No license, express or implied, is granted to any party for any purpose.
|
|
15
|
+
All rights are reserved by ArcBlock, Inc.
|
|
16
|
+
|
|
17
|
+
## Public Artifact Distribution
|
|
18
|
+
|
|
19
|
+
Portions of this Software may be released publicly under separate open-source
|
|
20
|
+
licenses (such as MIT License) through designated public repositories. Such
|
|
21
|
+
public releases are governed by their respective licenses and do not affect
|
|
22
|
+
the proprietary nature of this repository.
|
|
23
|
+
|
|
24
|
+
## Contact
|
|
25
|
+
|
|
26
|
+
For licensing inquiries, contact: legal@arcblock.io
|
package/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# @aigne/afs-ocap
|
|
2
|
+
|
|
3
|
+
AFS provider for the Arcblock OCAP verifiable ledger — read-only GraphQL-over-HTTPS view of transactions, accounts, tokens, factories, bridges, etc.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @aigne/afs-ocap
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { AFS } from "@aigne/afs";
|
|
15
|
+
import { AFSOCAP } from "@aigne/afs-ocap";
|
|
16
|
+
|
|
17
|
+
const afs = new AFS();
|
|
18
|
+
afs.mount(
|
|
19
|
+
new AFSOCAP({
|
|
20
|
+
endpoint: "https://main.abtnetwork.io/api",
|
|
21
|
+
name: "main-chain",
|
|
22
|
+
}),
|
|
23
|
+
"/dev/chain/main",
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
// Browse on-chain data
|
|
27
|
+
const blocks = await afs.list("/dev/chain/main/blocks");
|
|
28
|
+
const tx = await afs.read("/dev/chain/main/transactions/<hash>");
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The `BUILTIN_CHAIN_NETWORKS` constant from `@aigne/aos` covers `main` + `beta` so most setups don't need to mount manually — `arc service start` (Node) and `createAfsFromEnv` (Cloudflare Worker) auto-mount these chains under `/dev/chain/<network>` when `AFS_MOUNTS` doesn't already declare them.
|
|
32
|
+
|
|
33
|
+
## Companion AUP recipes
|
|
34
|
+
|
|
35
|
+
The `aup/` directory ships AUP recipes (e.g. `default.json`, `accounts/item.json`, `transactions/default.json`) that AFS projects as hidden supplements at `/dev/chain/<network>/.aup/<view>` so blocklets like `chain-explorer` can render rich UI without bundling chain-specific layout code.
|
|
36
|
+
|
|
37
|
+
Two delivery paths exist, transparent to consumers:
|
|
38
|
+
|
|
39
|
+
| Runtime | Path | Mechanism |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| Node | local filesystem | `loadPackageDirAsResources` reads `<package>/aup/` directly |
|
|
42
|
+
| Cloudflare Worker | `https://afsd-blocklets.pages.dev/_providers/ocap@<version>/` | `AFSHttpMount` fetches `.afs/manifest.json` + `.afs/bundle.json` |
|
|
43
|
+
|
|
44
|
+
The Worker can't read `node_modules` at runtime, so recipes are published to a CF Pages namespace alongside blocklets. URL embeds the package version so old workers always fetch their old recipes — no skew.
|
|
45
|
+
|
|
46
|
+
## Releasing
|
|
47
|
+
|
|
48
|
+
When publishing a new OCAP version:
|
|
49
|
+
|
|
50
|
+
1. **Bump `package.json` version** and merge to `main` (release-please handles version + changelog).
|
|
51
|
+
2. **Publish recipes to CF Pages** so the new Worker bundle (which inlines this version into URLs) finds them:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
arc provider publish-resources @aigne/afs-ocap \
|
|
55
|
+
--cloud cf \
|
|
56
|
+
--project afsd-blocklets \
|
|
57
|
+
--cf-account-id "$CF_ACCOUNT_ID" \
|
|
58
|
+
--cf-api-token "$CF_API_TOKEN"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This pushes `aup/**/*.json` to `/_providers/ocap@<version>/` on CF Pages (with `.afs/manifest.json` + `.afs/bundle.json` wrappers). CI should run this after release-please merges to `main`.
|
|
62
|
+
|
|
63
|
+
3. **Deploy the Worker** (any subsequent `arc worker deploy` cycle picks up the new `__OCAP_VERSION__` from `build.mjs`).
|
|
64
|
+
|
|
65
|
+
The order matters: if the Worker deploys before recipes are published, it will fail to fetch the new version's manifest and chain device AUP supplements will be silently absent (graceful-degrade — the data tree is still readable, just no AUP-styled UI). The publish step is idempotent, so re-running is safe.
|
|
66
|
+
|
|
67
|
+
For the local dev workflow (`arc worker dev`), recipes are served from `blocklets-dev-server` at `http://127.0.0.1:8788/_providers/ocap@<workspace-version>/` — no publish needed.
|
|
68
|
+
|
|
69
|
+
## Subscribe Capability
|
|
70
|
+
|
|
71
|
+
This provider opts into the AFS `subscribe` operation when the supplied
|
|
72
|
+
`OcapDataSource` exposes a working `subscribe(topic, callback)` primitive
|
|
73
|
+
(typically wrapping `@ocap/client.subscribe` over phoenix WS). The
|
|
74
|
+
capability manifest at `/<mount>/.meta/.capabilities` reports:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"operations": {
|
|
79
|
+
"subscribe": {
|
|
80
|
+
"supported": true,
|
|
81
|
+
"features": {
|
|
82
|
+
"live": true,
|
|
83
|
+
"eventTypes": "append,write",
|
|
84
|
+
"maxRateHz": 100,
|
|
85
|
+
"scope": "global"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The `live` flag reflects runtime reality: if the underlying source has no
|
|
93
|
+
`subscribe()` method, or if the install throws (e.g. the worker bundle
|
|
94
|
+
fails to import `@arcblock/ws`), the provider degrades to `live: false`
|
|
95
|
+
and continues serving reads. The mount itself never fails because of a
|
|
96
|
+
missing subscribe path.
|
|
97
|
+
|
|
98
|
+
When live is on, each upstream `tx.create` payload becomes an AFS
|
|
99
|
+
`afs:append` event at `<mount>/transactions/<hash>` carrying
|
|
100
|
+
`{ hash, type, time, sender, receiver }`. Consumers subscribe via
|
|
101
|
+
`afs.subscribe({ path: "/<mount>/transactions" }, callback)`. The
|
|
102
|
+
per-connection event broker (providers/runtime/ui) coalesces bursts and
|
|
103
|
+
paces by `maxRateHz`, so high-traffic chains don't flood the WS link.
|
|
104
|
+
|
|
105
|
+
Runtime behavior:
|
|
106
|
+
- **Node**: source dynamically imports `@ocap/client/subscribe`; the WS
|
|
107
|
+
client is whatever ships in the Node export condition.
|
|
108
|
+
- **Worker (Cloudflare)**: subscribe support is adapter-dependent — see
|
|
109
|
+
`planning/afs-ui/afs-live-updates/worker-research.md`. Workers that
|
|
110
|
+
cannot install the WS client report `live: false` and chain UIs fall
|
|
111
|
+
back to user-initiated refresh.
|
|
112
|
+
|
|
113
|
+
See `planning/afs-ui/afs-live-updates/` for the broader event vocabulary,
|
|
114
|
+
broker design, and the framework-level `_aupListBind` consumer.
|
|
115
|
+
|
|
116
|
+
## Typed where(`whereToOcapOptions` 适配器)
|
|
117
|
+
|
|
118
|
+
list 选项接受 typed `where`(afs-collection-query T5.3)——chain-explorer 的
|
|
119
|
+
tx filter Apply 即此形态。`listOpts()` 是唯一注入点:`options.where` 存在时,
|
|
120
|
+
`whereToOcapOptions()` 把 typed where 翻译成 7 个 `extract*Filters` 入口消费的
|
|
121
|
+
旧私有 option key(adapter 输出覆盖同名私有 key),**GQL 过滤结构逐字节不变**。
|
|
122
|
+
|
|
123
|
+
字段词汇表(OCAP 实体字段,design §3.2:词汇表语义归 provider):
|
|
124
|
+
|
|
125
|
+
| 类 | 字段 | 算子 |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| 标量 | sender / receiver / direction / validity / issuerAddress / ownerAddress / factoryAddress / tokenAddress / from / to | `eq` |
|
|
128
|
+
| 列表 | types / tokens / assets / factories / accounts / rollups / stakes / delegations / addressList | `eq`(单值)/ `in` |
|
|
129
|
+
| 时间 | `time` | `gte`→startDateTime / `lte`→endDateTime(ISO 串) |
|
|
130
|
+
|
|
131
|
+
安全两层(任一违反 = `AFSValidationError`,绝不触达 GQL 变量):
|
|
132
|
+
|
|
133
|
+
1. core 文法(dot-path 白名单、原型键拒绝、算子 arity);
|
|
134
|
+
2. 词汇表门——表外字段、类不允许的算子、非字符串值一律 strict 拒绝。
|
|
135
|
+
注入形值(如 `") { evil } #`)作为**数据**进 GQL variable,惰性无害。
|
|
136
|
+
|
|
137
|
+
空哨兵语义:`eq: ""` / `in: []`(表单未触碰态)= 不过滤,镜像 extractor 既有的
|
|
138
|
+
空值语义。测试:`test/where-adapter.test.ts`(7 extractor 等价 + 安全负例)。
|
|
139
|
+
|
|
140
|
+
## See also
|
|
141
|
+
|
|
142
|
+
- [`runtimes/cloudflare/README.md`](../../../runtimes/cloudflare/README.md) — Cloudflare worker dev workflow
|
|
143
|
+
- [`planning/provider-resource-distribution/`](../../../planning/provider-resource-distribution/README.md) — design rationale for the `_providers/<name>@<version>/` namespace
|
|
144
|
+
- [`planning/afs-ui/afs-live-updates/`](../../../planning/afs-ui/afs-live-updates/) — AFS event vocab + broker + OCAP producer design
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "accts-view",
|
|
3
|
+
"type": "view",
|
|
4
|
+
"props": {
|
|
5
|
+
"layout": {
|
|
6
|
+
"direction": "column",
|
|
7
|
+
"gap": "none"
|
|
8
|
+
},
|
|
9
|
+
"style": {
|
|
10
|
+
"flex": "1",
|
|
11
|
+
"overflow": "auto"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"children": [
|
|
15
|
+
{
|
|
16
|
+
"id": "accts-title",
|
|
17
|
+
"type": "text",
|
|
18
|
+
"props": { "content": "Accounts", "level": 1 }
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "accts-view-list",
|
|
22
|
+
"type": "afs-list",
|
|
23
|
+
"src": "${_parentPath}",
|
|
24
|
+
"props": {
|
|
25
|
+
"layout": "table",
|
|
26
|
+
"columns": [
|
|
27
|
+
{
|
|
28
|
+
"key": "content.address",
|
|
29
|
+
"label": "Address",
|
|
30
|
+
"mobileRole": "title",
|
|
31
|
+
"format": "did",
|
|
32
|
+
"width": "200px"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"key": "content._monikerDisplay",
|
|
36
|
+
"label": "Name",
|
|
37
|
+
"width": "150px"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"key": "content.genesisTime",
|
|
41
|
+
"label": "Created",
|
|
42
|
+
"format": "timeago",
|
|
43
|
+
"width": "120px"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"key": "content.renaissanceTime",
|
|
47
|
+
"label": "Updated",
|
|
48
|
+
"hideBelow": "tablet-wide",
|
|
49
|
+
"format": "timeago",
|
|
50
|
+
"width": "120px"
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"pageSize": 20,
|
|
54
|
+
"pagination": "manual",
|
|
55
|
+
"clickMode": "both",
|
|
56
|
+
"autoSelect": false,
|
|
57
|
+
"filter": {
|
|
58
|
+
"exclude": ".."
|
|
59
|
+
},
|
|
60
|
+
"showBreadcrumb": false
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|