@totemsdk/edge-adapters 0.1.0

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Totem SDK
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # @totemsdk/edge-adapters
2
+
3
+ Reference adapters bridging Totem SDK packages to `@totemsdk/edge` port interfaces.
4
+
5
+ ## What it does
6
+
7
+ Wires the Totem SDK into Edge's composable port-based runtime. Each adapter is a factory function that takes SDK dependencies and returns an object implementing the corresponding Edge port interface.
8
+
9
+ ## Adapters
10
+
11
+ | Adapter | Port Interface | SDK Dependency |
12
+ |---------|---------------|----------------|
13
+ | `createLiquidityPortAdapter` | `EdgeLiquidityPort` | `@totemsdk/chain-provider` |
14
+ | `createProofPortAdapter` | `EdgeProofPort` | `@totemsdk/proof` |
15
+ | `createLookupPortAdapter` | `EdgeLookupPort` | `@totemsdk/lookup-client` |
16
+ | `createPolicyPortAdapter` | `EdgePolicyPort` | `@totemsdk/agent-policy` |
17
+ | `createIdentityPortAdapter` | `EdgeIdentityPort` | `@totemsdk/identity` |
18
+ | `createManifestPortAdapter` | `EdgeManifestPort` | `@totemsdk/manifest` |
19
+ | `createMinimaL1PaymentPort` | `EdgePaymentPort` | `@totemsdk/root-identity` |
20
+ | `createOmniaL2PaymentPort` | `EdgePaymentPort` | `@totemsdk/omnia-router` |
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install @totemsdk/edge-adapters
26
+ ```
27
+
28
+ All SDK dependencies are optional peer dependencies — install only the ones you need for the adapters you use.
29
+
30
+ ## Usage
31
+
32
+ ```ts
33
+ import { createEdgeRuntime, createEdgeDevice, createCapabilitySet } from '@totemsdk/edge';
34
+ import { createLiquidityPortAdapter, createProofPortAdapter } from '@totemsdk/edge-adapters';
35
+ import { HostedProvider } from '@totemsdk/chain-provider';
36
+ import { createProof, signProof } from '@totemsdk/proof';
37
+
38
+ const chainProvider = new HostedProvider({ baseUrl: 'https://api.axia.to', apiKey: '...' });
39
+
40
+ const liquidityPort = createLiquidityPortAdapter({ chainProvider });
41
+ const proofPort = createProofPortAdapter({ createProof, signProof });
42
+
43
+ const device = createEdgeDevice({ deviceId: 'my-device' });
44
+ const capabilities = createCapabilitySet(['payment:send', 'proof:create']);
45
+ const runtime = createEdgeRuntime({ device, capabilities, ports: { liquidityPort, proofPort } });
46
+ ```
47
+
48
+ ## Out of scope
49
+
50
+ - Implementing port interfaces — those are defined in `@totemsdk/edge`
51
+ - Implementing SDK functionality — each adapter delegates to the corresponding SDK package
52
+ - Transport/networking — adapters are transport-agnostic
53
+
54
+ ## License
55
+
56
+ MIT
@@ -0,0 +1,19 @@
1
+ import type { IdentityGraph } from '@totemsdk/identity';
2
+ import type { EdgeIdentityPort } from '@totemsdk/edge';
3
+ export interface IdentityPortConfig {
4
+ /**
5
+ * The identity graph this adapter can resolve. Callers holding multiple
6
+ * identities should create one adapter per graph.
7
+ */
8
+ graph: IdentityGraph;
9
+ }
10
+ /**
11
+ * Wraps an IdentityGraph (from @totemsdk/identity) as an EdgeIdentityPort.
12
+ *
13
+ * resolve: returns the resolved identity when identityId matches graph.document.id,
14
+ * otherwise returns ok:false. For multi-identity setups, compose multiple
15
+ * adapters or use a router above this layer.
16
+ * verify: delegates to verifyIdentityClaim() for SignedIdentityClaim values.
17
+ * Returns ok:false for unrecognised proof shapes.
18
+ */
19
+ export declare function createIdentityPortAdapter(config: IdentityPortConfig): EdgeIdentityPort;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createIdentityPortAdapter = createIdentityPortAdapter;
4
+ const identity_1 = require("@totemsdk/identity");
5
+ /**
6
+ * Wraps an IdentityGraph (from @totemsdk/identity) as an EdgeIdentityPort.
7
+ *
8
+ * resolve: returns the resolved identity when identityId matches graph.document.id,
9
+ * otherwise returns ok:false. For multi-identity setups, compose multiple
10
+ * adapters or use a router above this layer.
11
+ * verify: delegates to verifyIdentityClaim() for SignedIdentityClaim values.
12
+ * Returns ok:false for unrecognised proof shapes.
13
+ */
14
+ function createIdentityPortAdapter(config) {
15
+ const { graph } = config;
16
+ return {
17
+ async resolve(identityId) {
18
+ try {
19
+ if (graph.document.id !== identityId) {
20
+ return {
21
+ ok: false,
22
+ error: `Identity "${identityId}" not found in this adapter's graph`,
23
+ errorCode: 'IDENTITY_NOT_FOUND',
24
+ };
25
+ }
26
+ const result = (0, identity_1.resolveIdentityGraph)(graph);
27
+ if (!result.resolved) {
28
+ return {
29
+ ok: false,
30
+ error: result.errors?.join('; ') ?? 'Identity could not be resolved',
31
+ errorCode: 'IDENTITY_UNRESOLVABLE',
32
+ };
33
+ }
34
+ return { ok: true, data: { identity: result.resolved } };
35
+ }
36
+ catch (err) {
37
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
38
+ }
39
+ },
40
+ async verify(proof) {
41
+ try {
42
+ const claim = proof;
43
+ if (!claim?.proof?.address) {
44
+ return {
45
+ ok: false,
46
+ error: 'Proof is not a recognisable SignedIdentityClaim',
47
+ errorCode: 'UNSUPPORTED_PROOF_TYPE',
48
+ };
49
+ }
50
+ const result = (0, identity_1.verifyIdentityClaim)(claim);
51
+ return {
52
+ ok: true,
53
+ data: { valid: result.valid, address: result.valid ? claim.proof.address : undefined },
54
+ };
55
+ }
56
+ catch (err) {
57
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
58
+ }
59
+ },
60
+ };
61
+ }
@@ -0,0 +1,13 @@
1
+ export { createLiquidityPortAdapter } from './liquidity.js';
2
+ export type { LiquidityPortConfig } from './liquidity.js';
3
+ export { createProofPortAdapter } from './proof.js';
4
+ export type { ProofPortConfig } from './proof.js';
5
+ export { createLookupPortAdapter } from './lookup.js';
6
+ export { createPolicyPortAdapter } from './policy.js';
7
+ export { createIdentityPortAdapter } from './identity.js';
8
+ export type { IdentityPortConfig } from './identity.js';
9
+ export { createManifestPortAdapter } from './manifest.js';
10
+ export { createMinimaL1PaymentPort } from './payment-l1.js';
11
+ export type { MinimaL1PaymentPortConfig } from './payment-l1.js';
12
+ export { createOmniaL2PaymentPort } from './payment-l2.js';
13
+ export type { OmniaL2PaymentPortConfig } from './payment-l2.js';
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createOmniaL2PaymentPort = exports.createMinimaL1PaymentPort = exports.createManifestPortAdapter = exports.createIdentityPortAdapter = exports.createPolicyPortAdapter = exports.createLookupPortAdapter = exports.createProofPortAdapter = exports.createLiquidityPortAdapter = void 0;
4
+ var liquidity_js_1 = require("./liquidity.js");
5
+ Object.defineProperty(exports, "createLiquidityPortAdapter", { enumerable: true, get: function () { return liquidity_js_1.createLiquidityPortAdapter; } });
6
+ var proof_js_1 = require("./proof.js");
7
+ Object.defineProperty(exports, "createProofPortAdapter", { enumerable: true, get: function () { return proof_js_1.createProofPortAdapter; } });
8
+ var lookup_js_1 = require("./lookup.js");
9
+ Object.defineProperty(exports, "createLookupPortAdapter", { enumerable: true, get: function () { return lookup_js_1.createLookupPortAdapter; } });
10
+ var policy_js_1 = require("./policy.js");
11
+ Object.defineProperty(exports, "createPolicyPortAdapter", { enumerable: true, get: function () { return policy_js_1.createPolicyPortAdapter; } });
12
+ var identity_js_1 = require("./identity.js");
13
+ Object.defineProperty(exports, "createIdentityPortAdapter", { enumerable: true, get: function () { return identity_js_1.createIdentityPortAdapter; } });
14
+ var manifest_js_1 = require("./manifest.js");
15
+ Object.defineProperty(exports, "createManifestPortAdapter", { enumerable: true, get: function () { return manifest_js_1.createManifestPortAdapter; } });
16
+ var payment_l1_js_1 = require("./payment-l1.js");
17
+ Object.defineProperty(exports, "createMinimaL1PaymentPort", { enumerable: true, get: function () { return payment_l1_js_1.createMinimaL1PaymentPort; } });
18
+ var payment_l2_js_1 = require("./payment-l2.js");
19
+ Object.defineProperty(exports, "createOmniaL2PaymentPort", { enumerable: true, get: function () { return payment_l2_js_1.createOmniaL2PaymentPort; } });
@@ -0,0 +1,15 @@
1
+ import type { ChainStateProvider } from '@totemsdk/chain-provider';
2
+ import type { EdgeLiquidityPort } from '@totemsdk/edge';
3
+ export interface LiquidityPortConfig {
4
+ provider: ChainStateProvider;
5
+ /** Token to sum when getBalance is called without an explicit tokenId. Defaults to '0x00' (native Minima). */
6
+ defaultTokenId?: string;
7
+ }
8
+ /**
9
+ * Wraps a ChainStateProvider (chain-provider, pureminima-rpc, lookup-client) as
10
+ * an EdgeLiquidityPort.
11
+ *
12
+ * getBalance sums sendable coins for the given address and tokenId.
13
+ * getUtxos returns all coins as raw UTXOs (typed as unknown[] per the port contract).
14
+ */
15
+ export declare function createLiquidityPortAdapter(config: LiquidityPortConfig): EdgeLiquidityPort;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createLiquidityPortAdapter = createLiquidityPortAdapter;
4
+ const _SCALE = 100000000n;
5
+ function _toScaled(s) {
6
+ const [i, f = ''] = s.split('.');
7
+ return BigInt(i || '0') * _SCALE + BigInt(f.padEnd(8, '0').slice(0, 8));
8
+ }
9
+ function _fromScaled(n) {
10
+ if (n === 0n)
11
+ return '0';
12
+ const frac = (n % _SCALE).toString().padStart(8, '0').replace(/0+$/, '');
13
+ return frac ? `${n / _SCALE}.${frac}` : `${n / _SCALE}`;
14
+ }
15
+ /**
16
+ * Wraps a ChainStateProvider (chain-provider, pureminima-rpc, lookup-client) as
17
+ * an EdgeLiquidityPort.
18
+ *
19
+ * getBalance sums sendable coins for the given address and tokenId.
20
+ * getUtxos returns all coins as raw UTXOs (typed as unknown[] per the port contract).
21
+ */
22
+ function createLiquidityPortAdapter(config) {
23
+ const { provider, defaultTokenId = '0x00' } = config;
24
+ return {
25
+ async getBalance(address) {
26
+ try {
27
+ const coins = await provider.getCoins({ address, tokenId: defaultTokenId, sendable: true });
28
+ const balance = _fromScaled(coins.reduce((sum, c) => sum + _toScaled(c.amount), 0n));
29
+ return { ok: true, data: { balance, tokenId: defaultTokenId } };
30
+ }
31
+ catch (err) {
32
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
33
+ }
34
+ },
35
+ async getUtxos(address) {
36
+ try {
37
+ const coins = await provider.getCoins({ address });
38
+ return { ok: true, data: { utxos: coins } };
39
+ }
40
+ catch (err) {
41
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
42
+ }
43
+ },
44
+ };
45
+ }
@@ -0,0 +1,13 @@
1
+ import type { LookupClient } from '@totemsdk/lookup-client';
2
+ import type { EdgeLookupPort } from '@totemsdk/edge';
3
+ /**
4
+ * Wraps a LookupClient as an EdgeLookupPort.
5
+ *
6
+ * lookup: queries coins by address, or a single coin by ID when kind === 'coin'.
7
+ * watch: registers for real-time coin-update push events.
8
+ * announce: encodes the caller's WOTS-signed manifest to bytes, then hands off
9
+ * to announceApp() or announceAgent() on the client. The client signs
10
+ * those bytes with its session Ed25519 keypair — no WOTS key index is
11
+ * consumed. Fire-and-forget: the lookup node sends no ACK.
12
+ */
13
+ export declare function createLookupPortAdapter(client: LookupClient): EdgeLookupPort;
package/dist/lookup.js ADDED
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createLookupPortAdapter = createLookupPortAdapter;
4
+ const manifest_1 = require("@totemsdk/manifest");
5
+ /**
6
+ * Wraps a LookupClient as an EdgeLookupPort.
7
+ *
8
+ * lookup: queries coins by address, or a single coin by ID when kind === 'coin'.
9
+ * watch: registers for real-time coin-update push events.
10
+ * announce: encodes the caller's WOTS-signed manifest to bytes, then hands off
11
+ * to announceApp() or announceAgent() on the client. The client signs
12
+ * those bytes with its session Ed25519 keypair — no WOTS key index is
13
+ * consumed. Fire-and-forget: the lookup node sends no ACK.
14
+ */
15
+ function createLookupPortAdapter(client) {
16
+ return {
17
+ async lookup(params) {
18
+ try {
19
+ if (params.kind === 'coin') {
20
+ const coin = await client.getCoin(params.query);
21
+ return { ok: true, data: { results: coin ? [coin] : [] } };
22
+ }
23
+ const coins = await client.getCoins({ address: params.query });
24
+ return { ok: true, data: { results: coins } };
25
+ }
26
+ catch (err) {
27
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
28
+ }
29
+ },
30
+ async watch(params) {
31
+ try {
32
+ const unsubscribe = client.subscribeCoinUpdates(params.onUpdate);
33
+ await client.watchAddress(params.address);
34
+ return { ok: true, data: { unsubscribe } };
35
+ }
36
+ catch (err) {
37
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
38
+ }
39
+ },
40
+ async announce(params) {
41
+ try {
42
+ const manifestBytes = (0, manifest_1.encodeManifest)(params.signed);
43
+ if (params.kind === 'app') {
44
+ await client.announceApp({
45
+ manifest: manifestBytes,
46
+ appId: params.appId,
47
+ expiresAt: params.expiresAt,
48
+ authorAddress: params.authorAddress,
49
+ isFree: params.isFree,
50
+ });
51
+ }
52
+ else {
53
+ await client.announceAgent({
54
+ manifest: manifestBytes,
55
+ capabilityId: params.capabilityId,
56
+ expiresAt: params.expiresAt,
57
+ tags: params.tags,
58
+ pricePerCall: params.pricePerCall,
59
+ latencyMs: params.latencyMs,
60
+ });
61
+ }
62
+ return { ok: true };
63
+ }
64
+ catch (err) {
65
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
66
+ }
67
+ },
68
+ async query(params) {
69
+ try {
70
+ if (params.kind === 'app') {
71
+ const apps = await client.queryApps({
72
+ category: params.category,
73
+ authorAddress: params.authorAddress,
74
+ minVersion: params.minVersion,
75
+ freeOnly: params.freeOnly,
76
+ limit: params.limit,
77
+ });
78
+ return { ok: true, data: { results: apps.map((a) => ({ id: a.appId, manifest: a.manifest, nodeId: a.nodeId })) } };
79
+ }
80
+ else {
81
+ const agents = await client.queryAgents({
82
+ capabilityName: params.capabilityName,
83
+ tags: params.tags,
84
+ maxPricePerCall: params.maxPricePerCall,
85
+ maxLatencyMs: params.maxLatencyMs,
86
+ limit: params.limit,
87
+ });
88
+ return { ok: true, data: { results: agents.map((a) => ({ id: a.capabilityId, manifest: a.manifest, nodeId: a.nodeId })) } };
89
+ }
90
+ }
91
+ catch (err) {
92
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
93
+ }
94
+ },
95
+ };
96
+ }
@@ -0,0 +1,11 @@
1
+ import type { EdgeManifestPort } from '@totemsdk/edge';
2
+ /**
3
+ * Wraps @totemsdk/manifest's signManifest / verifyManifest as an EdgeManifestPort.
4
+ *
5
+ * The port interface already carries seed and keyIndex at call time, so this
6
+ * adapter has no constructor config — it is purely a thin type bridge.
7
+ *
8
+ * Callers are responsible for key-lease reservation before calling sign().
9
+ * This adapter does not interact with @totemsdk/wots-lease.
10
+ */
11
+ export declare function createManifestPortAdapter(): EdgeManifestPort;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createManifestPortAdapter = createManifestPortAdapter;
4
+ const manifest_1 = require("@totemsdk/manifest");
5
+ /**
6
+ * Wraps @totemsdk/manifest's signManifest / verifyManifest as an EdgeManifestPort.
7
+ *
8
+ * The port interface already carries seed and keyIndex at call time, so this
9
+ * adapter has no constructor config — it is purely a thin type bridge.
10
+ *
11
+ * Callers are responsible for key-lease reservation before calling sign().
12
+ * This adapter does not interact with @totemsdk/wots-lease.
13
+ */
14
+ function createManifestPortAdapter() {
15
+ return {
16
+ async sign(manifest, seed, keyIndex) {
17
+ try {
18
+ const signed = await (0, manifest_1.signManifest)(manifest, seed, keyIndex);
19
+ return { ok: true, data: { signed } };
20
+ }
21
+ catch (err) {
22
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
23
+ }
24
+ },
25
+ async verify(signed) {
26
+ try {
27
+ const result = (0, manifest_1.verifyManifest)(signed);
28
+ return { ok: true, data: { valid: result.valid, reason: result.reason } };
29
+ }
30
+ catch (err) {
31
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
32
+ }
33
+ },
34
+ };
35
+ }
@@ -0,0 +1,38 @@
1
+ import type { ChainStateProvider } from '@totemsdk/chain-provider';
2
+ import type { EdgePaymentPort } from '@totemsdk/edge';
3
+ export interface MinimaL1PaymentPortConfig {
4
+ /** ChainStateProvider used to broadcast the signed TxPoW. */
5
+ provider: ChainStateProvider;
6
+ /**
7
+ * Injected signing function. Receives the payment intent and returns a
8
+ * fully mined TxPoW hex string ready for broadcast.
9
+ *
10
+ * This keeps the adapter agnostic to key management — callers wire in their
11
+ * own signer (e.g. @totemsdk/server's sendTransaction, a hardware wallet
12
+ * bridge, or a pureminima-rpc command sequence).
13
+ */
14
+ sign(params: {
15
+ toAddress: string;
16
+ amount: string;
17
+ tokenId: string;
18
+ memo?: string;
19
+ }): Promise<string>;
20
+ }
21
+ /**
22
+ * Minima L1 payment adapter.
23
+ *
24
+ * Delegates transaction construction and signing to the injected `sign` function,
25
+ * then broadcasts the result via the ChainStateProvider. This keeps key material
26
+ * out of the adapter entirely.
27
+ *
28
+ * For a batteries-included L1 adapter backed by @totemsdk/server's sendTransaction,
29
+ * wrap sendTransaction in the sign callback:
30
+ *
31
+ * createMinimaL1PaymentPort({
32
+ * provider: new PureMinimaRpcProvider(rpcConfig),
33
+ * sign: ({ toAddress, amount, tokenId }) =>
34
+ * sendTransaction({ seed, addressIndex, toAddress, amount, tokenId, ... })
35
+ * .then(r => r.minedHex),
36
+ * })
37
+ */
38
+ export declare function createMinimaL1PaymentPort(config: MinimaL1PaymentPortConfig): EdgePaymentPort;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createMinimaL1PaymentPort = createMinimaL1PaymentPort;
4
+ /**
5
+ * Minima L1 payment adapter.
6
+ *
7
+ * Delegates transaction construction and signing to the injected `sign` function,
8
+ * then broadcasts the result via the ChainStateProvider. This keeps key material
9
+ * out of the adapter entirely.
10
+ *
11
+ * For a batteries-included L1 adapter backed by @totemsdk/server's sendTransaction,
12
+ * wrap sendTransaction in the sign callback:
13
+ *
14
+ * createMinimaL1PaymentPort({
15
+ * provider: new PureMinimaRpcProvider(rpcConfig),
16
+ * sign: ({ toAddress, amount, tokenId }) =>
17
+ * sendTransaction({ seed, addressIndex, toAddress, amount, tokenId, ... })
18
+ * .then(r => r.minedHex),
19
+ * })
20
+ */
21
+ function createMinimaL1PaymentPort(config) {
22
+ return {
23
+ async pay(params) {
24
+ try {
25
+ const txpowHex = await config.sign({
26
+ toAddress: params.recipient,
27
+ amount: params.amount,
28
+ tokenId: params.tokenId ?? '0x00',
29
+ memo: params.memo,
30
+ });
31
+ const result = await config.provider.broadcastTxPoW(txpowHex);
32
+ if (!result.success) {
33
+ return {
34
+ ok: false,
35
+ error: result.message ?? 'Broadcast failed',
36
+ errorCode: 'BROADCAST_FAILED',
37
+ };
38
+ }
39
+ return { ok: true, data: { txpowId: result.txpowid } };
40
+ }
41
+ catch (err) {
42
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
43
+ }
44
+ },
45
+ };
46
+ }
@@ -0,0 +1,39 @@
1
+ import type { ChannelGraph, ChannelOps, RouterChannel, LeaseProvider, RouteOptions } from '@totemsdk/omnia-router';
2
+ import type { EdgePaymentPort } from '@totemsdk/edge';
3
+ export interface OmniaL2PaymentPortConfig {
4
+ /** Routing graph (edges + swap index). Updated externally as channels open/close. */
5
+ graph: ChannelGraph;
6
+ /**
7
+ * Live channel state keyed by channelId.
8
+ * executeMultiHopPayment mutates this map in-place as HTLCs are added/settled.
9
+ * Callers are responsible for keeping it in sync with the on-chain state.
10
+ */
11
+ channels: Map<string, RouterChannel>;
12
+ /** HTLC operations (addHTLC, fulfillHTLC, timeoutHTLC) for each channel. */
13
+ ops: ChannelOps;
14
+ /** WOTS lease providers keyed by channelId — required for HTLC signing. */
15
+ leaseProviders: Map<string, LeaseProvider>;
16
+ /** Public key digest identifying the local party in each channel. */
17
+ localPublicKeyDigest: string;
18
+ /**
19
+ * Returns the current chain block height. Used to compute HTLC expiry.
20
+ * Typically: `async () => BigInt((await provider.getTip()).block)`.
21
+ */
22
+ getCurrentBlock(): Promise<bigint>;
23
+ /** HTLC timeout in blocks past the current tip. Defaults to 144 (≈24h on Minima). */
24
+ htlcTimeoutBlocks?: bigint;
25
+ /** Optional pathfinding overrides forwarded to findRoute. */
26
+ routeOptions?: RouteOptions;
27
+ }
28
+ /**
29
+ * Omnia L2 payment adapter.
30
+ *
31
+ * Routes payments over Omnia payment channels using multi-hop HTLC execution.
32
+ * The local node must already have open channels forming a path to the recipient.
33
+ *
34
+ * pay() finds a route, builds a PaymentRequest, and executes atomically:
35
+ * 1. Forward phase — locks HTLCs across each hop.
36
+ * 2. Reveal phase — reveals the preimage in reverse to settle all hops.
37
+ * Rollback (best-effort timeoutHTLC) fires on any failure.
38
+ */
39
+ export declare function createOmniaL2PaymentPort(config: OmniaL2PaymentPortConfig): EdgePaymentPort;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createOmniaL2PaymentPort = createOmniaL2PaymentPort;
4
+ const omnia_router_1 = require("@totemsdk/omnia-router");
5
+ const _SCALE = 100000000n;
6
+ function _toScaled(s) {
7
+ const [i, f = ''] = s.split('.');
8
+ return BigInt(i || '0') * _SCALE + BigInt(f.padEnd(8, '0').slice(0, 8));
9
+ }
10
+ /**
11
+ * Omnia L2 payment adapter.
12
+ *
13
+ * Routes payments over Omnia payment channels using multi-hop HTLC execution.
14
+ * The local node must already have open channels forming a path to the recipient.
15
+ *
16
+ * pay() finds a route, builds a PaymentRequest, and executes atomically:
17
+ * 1. Forward phase — locks HTLCs across each hop.
18
+ * 2. Reveal phase — reveals the preimage in reverse to settle all hops.
19
+ * Rollback (best-effort timeoutHTLC) fires on any failure.
20
+ */
21
+ function createOmniaL2PaymentPort(config) {
22
+ const htlcTimeoutBlocks = config.htlcTimeoutBlocks ?? 144n;
23
+ return {
24
+ async pay(params) {
25
+ try {
26
+ const tokenId = params.tokenId ?? '0x00';
27
+ const amount = _toScaled(params.amount);
28
+ const route = (0, omnia_router_1.findRoute)(config.graph, config.localPublicKeyDigest, params.recipient, amount, tokenId, config.routeOptions);
29
+ if (!route) {
30
+ return {
31
+ ok: false,
32
+ error: `No route found to ${params.recipient} for amount ${params.amount} (${tokenId})`,
33
+ errorCode: 'NO_ROUTE',
34
+ };
35
+ }
36
+ const currentBlock = await config.getCurrentBlock();
37
+ const expiryBlock = currentBlock + htlcTimeoutBlocks;
38
+ const request = (0, omnia_router_1.buildPaymentRequest)(amount, tokenId, expiryBlock);
39
+ const result = await (0, omnia_router_1.executeMultiHopPayment)(config.ops, config.channels, route, request, config.leaseProviders);
40
+ if (!result.success) {
41
+ return {
42
+ ok: false,
43
+ error: result.error ?? 'Multi-hop payment failed',
44
+ errorCode: 'PAYMENT_FAILED',
45
+ };
46
+ }
47
+ return { ok: true, data: { txpowId: result.preimage } };
48
+ }
49
+ catch (err) {
50
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
51
+ }
52
+ },
53
+ };
54
+ }
@@ -0,0 +1,11 @@
1
+ import type { AgentPolicy } from '@totemsdk/agent-policy';
2
+ import type { EdgePolicyPort } from '@totemsdk/edge';
3
+ /**
4
+ * Wraps an AgentPolicy as an EdgePolicyPort.
5
+ *
6
+ * Builds a minimal AgentProposal from the EdgePolicyPort check() params and
7
+ * delegates to policy.canAutoApprove(). The intent type is inferred from the
8
+ * action string (actions starting with 'pay' map to 'payment'; everything
9
+ * else maps to 'receipt' as a catch-all).
10
+ */
11
+ export declare function createPolicyPortAdapter(policy: AgentPolicy): EdgePolicyPort;
package/dist/policy.js ADDED
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPolicyPortAdapter = createPolicyPortAdapter;
4
+ /**
5
+ * Wraps an AgentPolicy as an EdgePolicyPort.
6
+ *
7
+ * Builds a minimal AgentProposal from the EdgePolicyPort check() params and
8
+ * delegates to policy.canAutoApprove(). The intent type is inferred from the
9
+ * action string (actions starting with 'pay' map to 'payment'; everything
10
+ * else maps to 'receipt' as a catch-all).
11
+ */
12
+ function createPolicyPortAdapter(policy) {
13
+ return {
14
+ async check(params) {
15
+ try {
16
+ const intentType = params.action.startsWith('pay') ? 'payment' : 'receipt';
17
+ const proposal = {
18
+ id: `edge-policy-${params.action}-${params.subject}-${Date.now()}`,
19
+ agentId: 'edge-policy-adapter',
20
+ intent: {
21
+ type: intentType,
22
+ recipient: params.subject,
23
+ reason: params.action,
24
+ risk: params.context?.['risk'] ?? 'low',
25
+ metadata: params.context,
26
+ },
27
+ explanation: `Policy check for action "${params.action}" by subject "${params.subject}"`,
28
+ confidence: 1,
29
+ createdAt: Date.now(),
30
+ };
31
+ const allowed = await policy.canAutoApprove(proposal);
32
+ return {
33
+ ok: true,
34
+ data: {
35
+ allowed,
36
+ reason: allowed ? undefined : 'Action requires user approval per configured policy',
37
+ },
38
+ };
39
+ }
40
+ catch (err) {
41
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
42
+ }
43
+ },
44
+ };
45
+ }
@@ -0,0 +1,18 @@
1
+ import type { ProofProvider, ProofKind } from '@totemsdk/proof';
2
+ import type { EdgeProofPort } from '@totemsdk/edge';
3
+ export interface ProofPortConfig {
4
+ provider: ProofProvider;
5
+ /** Issuer address or identifier stamped onto created proofs. */
6
+ issuer: string;
7
+ /** Default proof kind when callers don't specify one via context. */
8
+ defaultKind?: ProofKind;
9
+ }
10
+ /**
11
+ * Wraps a ProofProvider (e.g. proof-integritas) as an EdgeProofPort.
12
+ *
13
+ * createProof: builds an unsigned proof from the EdgeProofPort params, then
14
+ * stamps its canonical hash via provider.stampHash if available.
15
+ * verifyProof: delegates to provider.verifyProof for SignedProof values,
16
+ * or provider.checkProof for lightweight existence checks.
17
+ */
18
+ export declare function createProofPortAdapter(config: ProofPortConfig): EdgeProofPort;
package/dist/proof.js ADDED
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createProofPortAdapter = createProofPortAdapter;
4
+ const proof_1 = require("@totemsdk/proof");
5
+ /**
6
+ * Wraps a ProofProvider (e.g. proof-integritas) as an EdgeProofPort.
7
+ *
8
+ * createProof: builds an unsigned proof from the EdgeProofPort params, then
9
+ * stamps its canonical hash via provider.stampHash if available.
10
+ * verifyProof: delegates to provider.verifyProof for SignedProof values,
11
+ * or provider.checkProof for lightweight existence checks.
12
+ */
13
+ function createProofPortAdapter(config) {
14
+ const { provider, issuer, defaultKind = 'attestation' } = config;
15
+ return {
16
+ async createProof(params) {
17
+ try {
18
+ const kind = params.context?.['kind'] ?? defaultKind;
19
+ const unsigned = (0, proof_1.createProof)({
20
+ kind,
21
+ subject: { id: params.subject, kind: 'edge-subject' },
22
+ issuer,
23
+ payload: { claims: params.claims, ...(params.context ?? {}) },
24
+ });
25
+ // Stamp the proof's canonical hash if the provider supports it.
26
+ if (provider.stampHash) {
27
+ const hash = (0, proof_1.toHex)(new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder().encode((0, proof_1.canonicalJson)(unsigned)))));
28
+ await provider.stampHash({ hash });
29
+ }
30
+ return { ok: true, data: { proofId: unsigned.proofId, proof: unsigned } };
31
+ }
32
+ catch (err) {
33
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
34
+ }
35
+ },
36
+ async verifyProof(params) {
37
+ try {
38
+ const proof = params.proof;
39
+ if (provider.verifyProof) {
40
+ const result = await provider.verifyProof(proof);
41
+ return { ok: true, data: { valid: result.valid, reason: result.reason } };
42
+ }
43
+ if (provider.checkProof) {
44
+ const result = await provider.checkProof(proof);
45
+ const valid = result.ok && !result.error;
46
+ return { ok: true, data: { valid, reason: result.error } };
47
+ }
48
+ return {
49
+ ok: false,
50
+ error: 'Provider does not support proof verification',
51
+ errorCode: 'NO_VERIFY_CAPABILITY',
52
+ };
53
+ }
54
+ catch (err) {
55
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
56
+ }
57
+ },
58
+ };
59
+ }
package/package.json ADDED
@@ -0,0 +1,98 @@
1
+ {
2
+ "name": "@totemsdk/edge-adapters",
3
+ "version": "0.1.0",
4
+ "description": "Reference adapters bridging Totem SDK packages to @totemsdk/edge port interfaces",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "require": "./dist/index.js",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "prepare": "tsc",
17
+ "clean": "rm -rf dist",
18
+ "test": "jest --passWithNoTests"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "README.md",
23
+ "LICENSE"
24
+ ],
25
+ "peerDependencies": {
26
+ "@totemsdk/agent-policy": "^0.1.3",
27
+ "@totemsdk/chain-provider": "^0.1.4",
28
+ "@totemsdk/identity": "^0.1.2",
29
+ "@totemsdk/lookup-client": "^0.1.4",
30
+ "@totemsdk/manifest": "^0.1.2",
31
+ "@totemsdk/omnia-router": "^0.1.4",
32
+ "@totemsdk/proof": "^0.1.1",
33
+ "@totemsdk/root-identity": "^1.0.7"
34
+ },
35
+ "peerDependenciesMeta": {
36
+ "@totemsdk/agent-policy": {
37
+ "optional": true
38
+ },
39
+ "@totemsdk/chain-provider": {
40
+ "optional": true
41
+ },
42
+ "@totemsdk/identity": {
43
+ "optional": true
44
+ },
45
+ "@totemsdk/manifest": {
46
+ "optional": true
47
+ },
48
+ "@totemsdk/omnia-router": {
49
+ "optional": true
50
+ },
51
+ "@totemsdk/proof": {
52
+ "optional": true
53
+ },
54
+ "@totemsdk/lookup-client": {
55
+ "optional": true
56
+ },
57
+ "@totemsdk/root-identity": {
58
+ "optional": true
59
+ }
60
+ },
61
+ "devDependencies": {
62
+ "@totemsdk/agent-policy": "^0.1.3",
63
+ "@totemsdk/chain-provider": "^0.1.4",
64
+ "@totemsdk/edge": "^0.1.3",
65
+ "@totemsdk/identity": "^0.1.2",
66
+ "@totemsdk/lookup-client": "^0.1.5",
67
+ "@totemsdk/manifest": "^0.1.2",
68
+ "@totemsdk/omnia-router": "^0.1.4",
69
+ "@totemsdk/proof": "^0.1.1",
70
+ "@totemsdk/root-identity": "^1.0.7",
71
+ "@types/jest": "^29.0.0",
72
+ "@types/node": "^20.0.0",
73
+ "jest": "^29.0.0",
74
+ "ts-jest": "^29.0.0",
75
+ "typescript": "^5.0.0"
76
+ },
77
+ "engines": {
78
+ "node": ">=18.0.0"
79
+ },
80
+ "publishConfig": {
81
+ "access": "public"
82
+ },
83
+ "license": "MIT",
84
+ "author": "Totem SDK",
85
+ "homepage": "https://totemsdk.com",
86
+ "repository": {
87
+ "type": "git",
88
+ "url": "git+https://github.com/MrGheek/axia-totem.git",
89
+ "directory": "packages/totem-sdk/packages/edge-adapters"
90
+ },
91
+ "keywords": [
92
+ "totem",
93
+ "totemsdk",
94
+ "edge",
95
+ "adapters",
96
+ "ports"
97
+ ]
98
+ }