PolywrapClient Config Builder
A utility class for building the PolywrapClient config.
Supports building configs using method chaining or imperatively.
Quickstart
Initialize
Initialize a ClientConfigBuilder using the constructor
const builder = new ClientConfigBuilder();
Configure
Add client configuration with add, or flexibly mix and match builder configuration methods to add and remove configuration items.
builder.add({
envs: {},
interfaces: {},
redirects: {},
wrappers: {},
packages: {},
resolvers: [],
});
builder
.addPackage("wrap://plugin/package", httpPlugin({}))
.removePackage("wrap://plugin/package")
.addPackages(
{
"wrap://plugin/http": httpPlugin({}),
"wrap://plugin/filesystem": fileSystemPlugin({}),
}
);
You can add the entire default client configuration bundle at once with addDefaults
builder.addDefaults();
Build
Finally, build a ClientConfig or CoreClientConfig to pass to the PolywrapClient constructor.
let coreClientConfig = builder.build();
coreClientConfig = builder.build({
wrapperCache: new WrapperCache(),
});
coreClientConfig = builder.build({
resolver: RecursiveResolver.from([]),
});
Example
A complete example using all or most of the available methods.
// init
const builder = new ClientConfigBuilder();
// add the default bundle first to override its entries later
builder.addDefaults();
// add many config items at once
builder.add({
envs: {},
interfaces: {},
redirects: {},
wrappers: {},
packages: {},
resolvers: [],
});
// add and remove wrappers
builder
.addWrapper("wrap://ens/wrapper.eth", await WasmWrapper.from(
new Uint8Array([1, 2, 3]),
new Uint8Array([1, 2, 3])
))
.removeWrapper("wrap://ens/wrapper.eth")
.addWrappers({
"wrap://ens/wrapper.eth": await WasmWrapper.from(
new Uint8Array([1, 2, 3]),
new Uint8Array([1, 2, 3])
)}
);
// add and remove wrap packages
builder
.addPackage("wrap://plugin/package", httpPlugin({}))
.removePackage("wrap://plugin/package")
.addPackages({
"wrap://plugin/package": httpPlugin({})
})
// add and remove Envs
builder
.addEnv("wrap://ens/wrapper.eth", { key: "value" })
.removeEnv("wrap://ens/wrapper.eth")
.addEnvs({
"wrap://ens/wrapper.eth": { key: "value" },
});
// override existing Env, or add new Env if one is not registered at URI
builder.setEnv("wrap://ens/wrapper.eth", { key: "value" });
// add or remove registration for an implementation of an interface
builder
.addInterfaceImplementation(
"wrap://ens/interface.eth",
"wrap://ens/wrapper.eth"
)
.removeInterfaceImplementation(
"wrap://ens/interface.eth",
"wrap://ens/wrapper.eth"
)
.addInterfaceImplementations("wrap://ens/interface.eth", [
"wrap://ens/wrapper.eth",
]);
// add or remove URI redirects
builder
.addRedirect("wrap://ens/from.eth", "wrap://ens/to.eth")
.removeRedirect("wrap://ens/from.eth")
.addRedirects({
"wrap://ens/from.eth": "wrap://ens/to.eth",
});
// add resolvers
builder.addResolver(RecursiveResolver.from([]));
builder.addResolvers([]);
// build
const clientConfig = builder.build();
Reference
ClientConfigBuilder
Constructor
constructor()
add
add(config: Partial<BuilderConfig>): IClientConfigBuilder;
addWrapper
addWrapper(uri: string, wrapper: Wrapper): IClientConfigBuilder;
addWrappers
addWrappers(uriWrappers: Record<string, Wrapper>): IClientConfigBuilder;
removeWrapper
removeWrapper(uri: string): IClientConfigBuilder;
addPackage
addPackage(uri: string, wrapPackage: IWrapPackage): IClientConfigBuilder;
addPackages
addPackages(uriPackages: Record<string, IWrapPackage>): IClientConfigBuilder;
removePackage
removePackage(uri: string): IClientConfigBuilder;
addEnv
addEnv(uri: string, env: Record<string, unknown>): IClientConfigBuilder;
addEnvs
addEnvs(
uriEnvs: Record<string, Record<string, unknown>>
): IClientConfigBuilder;
removeEnv
removeEnv(uri: string): IClientConfigBuilder;
setEnv
setEnv(uri: string, env: Record<string, unknown>): IClientConfigBuilder;
addInterfaceImplementation
addInterfaceImplementation(
interfaceUri: string,
implementationUri: string
): IClientConfigBuilder;
addInterfaceImplementations
addInterfaceImplementations(
interfaceUri: string,
implementationUris: Array<string>
): IClientConfigBuilder;
removeInterfaceImplementation
removeInterfaceImplementation(
interfaceUri: string,
implementationUri: string
): IClientConfigBuilder;
addRedirect
addRedirect(from: string, to: string): IClientConfigBuilder;
addRedirects
addRedirects(redirects: Record<string, string>): IClientConfigBuilder;
removeRedirect
removeRedirect(from: string): IClientConfigBuilder;
addResolver
addResolver(resolver: UriResolverLike): IClientConfigBuilder;
addResolvers
addResolvers(resolvers: UriResolverLike[]): IClientConfigBuilder;
addDefaults
addDefaults(): IClientConfigBuilder;
build
build(options?: BuildOptions): CoreClientConfig;
Bundles
Bundle: DefaultConfig
export const ipfsProviders: string[] = [
"https://ipfs.wrappers.io",
"https://ipfs.io",
];
interface IDefaultEmbed {
uri: Uri;
package: IWrapPackage;
source: Uri;
}
interface IDefaultEmbeds {
ipfsHttpClient: IDefaultEmbed;
ipfsResolver: IDefaultEmbed;
}
export const embeds: IDefaultEmbeds = {
ipfsHttpClient: {
uri: Uri.from("embed/ipfs-http-client@1.0.0"),
package: ipfsHttpClient.wasmPackage,
source: Uri.from("ens/wraps.eth:ipfs-http-client@1.0.0"),
},
ipfsResolver: {
uri: Uri.from("embed/async-ipfs-uri-resolver-ext@1.0.0"),
package: ipfsResolver.wasmPackage,
source: Uri.from("ens/wraps.eth:async-ipfs-uri-resolver-ext@1.0.0"),
},
};
type UriResolverExtBootloader = [IDefaultEmbed, IUriRedirect, ...Uri[]];
export const uriResolverExts: UriResolverExtBootloader = [
embeds.ipfsResolver,
{
from: Uri.from("ens/wraps.eth:ens-text-record-uri-resolver-ext@1.0.0"),
to: Uri.from("ipfs/QmaM318ABUXDhc5eZGGbmDxkb2ZgnbLxigm5TyZcCsh1Kw"),
},
Uri.from("ens/wraps.eth:http-uri-resolver-ext@1.0.0"),
Uri.from("ens/wraps.eth:file-system-uri-resolver-ext@1.0.0"),
Uri.from("ens/wraps.eth:ens-uri-resolver-ext@1.0.0"),
Uri.from("ens/wraps.eth:ens-ipfs-contenthash-uri-resolver-ext@1.0.0"),
Uri.from("ens/wraps.eth:ens-ocr-contenthash-uri-resolver-ext@1.0.0"),
];
interface IDefaultPlugin {
uri: Uri;
plugin: PluginPackage<unknown>;
implements: Uri[];
}
interface IDefaultPlugins {
logger: IDefaultPlugin;
http: IDefaultPlugin;
fileSystem: IDefaultPlugin;
concurrent: IDefaultPlugin;
ethereumProvider: IDefaultPlugin;
}
export const plugins: IDefaultPlugins = {
logger: {
uri: Uri.from("plugin/logger@1.0.0"),
plugin: loggerPlugin({}),
implements: [Uri.from("ens/wraps.eth:logger@1.0.0")],
},
http: {
uri: Uri.from("plugin/http@1.1.0"),
plugin: httpPlugin({}),
implements: [
Uri.from("ens/wraps.eth:http@1.1.0"),
Uri.from("ens/wraps.eth:http@1.0.0"),
],
},
fileSystem: {
uri: Uri.from("plugin/file-system@1.0.0"),
plugin: fileSystemPlugin({}),
implements: [Uri.from("ens/wraps.eth:file-system@1.0.0")],
},
concurrent: {
uri: Uri.from("plugin/concurrent@1.0.0"),
plugin: concurrentPromisePlugin({}),
implements: [Uri.from("ens/wraps.eth:concurrent@1.0.0")],
},
ethereumProvider: {
uri: Uri.from("plugin/ethereum-provider@1.1.0"),
plugin: ethereumProviderPlugin({
connections: new Connections({
networks: {
mainnet: new Connection({
provider:
"https://mainnet.infura.io/v3/b00b2c2cc09c487685e9fb061256d6a6",
}),
goerli: new Connection({
provider:
"https://goerli.infura.io/v3/b00b2c2cc09c487685e9fb061256d6a6",
}),
},
}),
}),
implements: [
Uri.from("ens/wraps.eth:ethereum-provider@1.1.0"),
Uri.from("ens/wraps.eth:ethereum-provider@1.0.0"),
],
},
};
export function getConfig(): BuilderConfig {
const builder = new ClientConfigBuilder();
for (const embed of Object.values(embeds)) {
builder.addPackage(embed.uri.uri, embed.package);
builder.addRedirect(embed.source.uri, embed.uri.uri);
builder.addInterfaceImplementation(embed.source.uri, embed.uri.uri);
}
for (const plugin of Object.values(plugins)) {
builder.addPackage(plugin.uri.uri, plugin.plugin);
for (const interfaceUri of plugin.implements) {
builder.addInterfaceImplementation(interfaceUri.uri, plugin.uri.uri);
builder.addRedirect(interfaceUri.uri, plugin.uri.uri);
}
}
builder.addInterfaceImplementations(
ExtendableUriResolver.defaultExtInterfaceUris[0].uri,
[
uriResolverExts[0].source.uri,
uriResolverExts[1].from.uri,
...uriResolverExts.slice(2).map((x: Uri) => x.uri),
]
);
builder.addRedirect(uriResolverExts[1].from.uri, uriResolverExts[1].to.uri);
builder.addEnv(embeds.ipfsResolver.source.uri, {
provider: ipfsProviders[0],
fallbackProviders: ipfsProviders.slice(1),
retries: { tryResolveUri: 2, getFile: 2 },
});
return builder.config;
}