Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | 2x 5x 5x 5x 5x 5x 9x 5x 5x | import { E } from '@endo/eventual-send';
import { GET_INTERFACE_GUARD } from '@endo/exo';
import { getInterfaceGuardPayload } from '@endo/patterns';
import type { InterfaceGuard, MethodGuard } from '@endo/patterns';
import { ifDefined } from '@metamask/kernel-utils';
import { makeSection } from './section.ts';
import type { MetadataSpec, Provider } from './types.ts';
/**
* Wrap a remote (CapTP) reference as a Provider.
*
* The sheaf requires synchronous [GET_INTERFACE_GUARD] access on every section,
* but remote references are opaque CapTP handles that cannot provide this
* synchronously. This function fetches the guard from the remote via E() once
* at construction time, then creates a local wrapper exo that carries it and
* forwards every method call back to the remote via E().
*
* @param name - Name for the wrapper exo.
* @param remoteRef - The remote reference to forward calls to.
* @param metadata - Optional metadata spec for the provider.
* @returns A Provider whose exo forwards method calls to the remote.
*/
export const makeRemoteSection = async <M extends Record<string, unknown>>(
name: string,
remoteRef: object,
metadata?: MetadataSpec<M>,
): Promise<Provider<M>> => {
const interfaceGuard: InterfaceGuard = await (
E(remoteRef) as unknown as {
[GET_INTERFACE_GUARD](): Promise<InterfaceGuard>;
}
)[GET_INTERFACE_GUARD]();
const { methodGuards } = getInterfaceGuardPayload(
interfaceGuard,
) as unknown as {
methodGuards: Record<string, MethodGuard>;
};
const remote = remoteRef as unknown as Record<
string,
(...args: unknown[]) => Promise<unknown>
>;
const handlers: Record<string, (...args: unknown[]) => Promise<unknown>> = {};
for (const method of Object.keys(methodGuards)) {
handlers[method] = async (...args: unknown[]) =>
// method is always present: it comes from Object.keys(methodGuards)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
(E(remote) as Record<string, (...a: unknown[]) => Promise<unknown>>)[
method
]!(...args);
}
const exo = makeSection(name, interfaceGuard, handlers);
return ifDefined({ exo, metadata }) as Provider<M>;
};
|