@nfid/identitykit
Version:
A React library for adding wallet connections to dApps.
503 lines (494 loc) • 55 kB
JavaScript
'use client';
export { SignerAgent } from '@slide-computer/signer-agent';
import { Principal } from '@dfinity/principal';
import { AnonymousIdentity } from '@dfinity/agent';
import { Ed25519KeyIdentity, ECDSAKeyIdentity, isDelegationValid, PartialIdentity, PartialDelegationIdentity, DelegationIdentity, DelegationChain, Delegation } from '@dfinity/identity';
import { IdbStorage, getIdentity, getDelegationChain, setIdentity, setDelegationChain, removeIdentity, removeDelegationChain } from '@slide-computer/signer-storage';
import { SubAccount, LedgerCanister, AccountIdentifier } from '@dfinity/ledger-icp';
import { toBase64, fromBase64 } from '@slide-computer/signer';
export { fromBase64, toBase64 } from '@slide-computer/signer';
class Agent {
signerAgentStrategy;
agentStrategy;
delegation;
constructor(signerAgentStrategy, agentStrategy, delegation) {
this.signerAgentStrategy = signerAgentStrategy;
this.agentStrategy = agentStrategy;
this.delegation = delegation;
}
static async create({ delegation, signerAgent, agent }) {
return new Agent(signerAgent, agent, delegation);
}
async call(...params) {
const delegationTargets = this.delegation?.targets;
const strategy = this.delegation &&
(!delegationTargets?.length ||
delegationTargets?.find((t) => t.compareTo(Principal.from(params[0])) === "eq"))
? this.agentStrategy
: this.signerAgentStrategy;
return strategy.call(...params);
}
async query(...params) {
const delegationTargets = this.delegation?.targets;
const strategy = this.delegation &&
(!delegationTargets?.length ||
delegationTargets?.find((t) => t.compareTo(Principal.from(params[0])) === "eq"))
? this.agentStrategy
: this.signerAgentStrategy;
return strategy.query(...params);
}
get rootKey() {
return this.agentStrategy.rootKey;
}
async fetchRootKey() {
return this.agentStrategy.fetchRootKey();
}
async getPrincipal() {
return this.agentStrategy.getPrincipal();
}
async status() {
return this.agentStrategy.status();
}
async readState(...params) {
const delegationTargets = this.delegation?.targets;
const strategy = this.delegation &&
(!delegationTargets?.length ||
delegationTargets?.find((t) => t.compareTo(Principal.from(params[0])) === "eq"))
? this.agentStrategy
: this.signerAgentStrategy;
return strategy.readState(...params);
}
async createReadStateRequest(...params) {
return this.agentStrategy.createReadStateRequest?.(...params);
}
}
const DEFAULT_MAX_TIME_TO_LIVE = BigInt(1.8e12); // 30 min
const DEFAULT_IDLE_TIMEOUT = 14_400_000; // 4 hours
const TIMEOUT_MAX_DELAY = 2147483647;
/**
* Detects if the `timeout` ms is over, and calls `onTimeout` and registered callbacks.
* To override these defaults, you can pass an `onTimeout` callback, or configure a custom `timeout` in milliseconds
*/
class TimeoutManager {
callbacks = [];
timeout;
timeoutID = undefined;
/**
* @param options {@link IdleManagerOptions}
*/
constructor(options) {
const { onTimeout, timeout } = options || {};
this.callbacks = onTimeout ? [onTimeout] : [];
this.timeout = timeout > TIMEOUT_MAX_DELAY ? TIMEOUT_MAX_DELAY : timeout;
const _resetTimer = this._resetTimer.bind(this);
window.addEventListener("load", _resetTimer, true);
_resetTimer();
}
/**
* @param {TimeoutCB} callback function to be called on timeout
*/
registerCallback(callback) {
this.callbacks.push(callback);
}
/**
* Cleans up the timeout manager and its listeners
*/
exit() {
clearTimeout(this.timeoutID);
window.removeEventListener("load", this._resetTimer, true);
}
/**
* Resets the timeouts during cleanup
*/
_resetTimer() {
window.clearTimeout(this.timeoutID);
this.timeoutID = window.setTimeout(() => {
this.callbacks.forEach((cb) => cb());
}, this.timeout);
}
}
const events = ["mousedown", "mousemove", "keydown", "touchstart", "wheel"];
/**
* Detects if the user has been idle for a duration of `idleTimeout` ms, and calls `onIdle` and registered callbacks.
* By default, the IdleManager will log a user out after 10 minutes of inactivity.
* To override these defaults, you can pass an `onIdle` callback, or configure a custom `idleTimeout` in milliseconds
*/
class IdleManager extends TimeoutManager {
constructor(options = {}) {
super({ timeout: options.idleTimeout || DEFAULT_IDLE_TIMEOUT, onTimeout: options.onIdle });
const _resetTimer = this._resetTimer.bind(this);
events.forEach(function (name) {
document.addEventListener(name, _resetTimer, true);
});
const debounce = (func, wait) => {
let timeout;
return (...args) => {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const context = this;
const later = function () {
timeout = undefined;
func.apply(context, args);
};
clearTimeout(timeout);
timeout = window.setTimeout(later, wait);
};
};
if (options?.captureScroll) {
// debounce scroll events
const scroll = debounce(_resetTimer, options?.scrollDebounce ?? 100);
window.addEventListener("scroll", scroll, true);
}
}
}
const STORAGE_KEY = "client";
const STORAGE_CONNECTED_OWNER_KEY = "connected-owner";
const STORAGE_CONNECTED_SUBACCOUNT_KEY = "connected-subaccount";
class SignerClient {
options;
idleManager;
storage = new IdbStorage();
connectedUser;
constructor(options) {
this.options = options;
if (!options?.idleOptions?.disableIdle) {
this.idleManager = new IdleManager(options.idleOptions);
this.registerDefaultIdleCallback();
}
if (options.storage)
this.storage = options.storage;
}
registerDefaultIdleCallback() {
/**
* Default behavior is to clear stored identity and reload the page.
* By either setting the disableDefaultIdleCallback flag or passing in a custom idle callback, we will ignore this config
*/
if (!this.options?.idleOptions?.disableDefaultIdleCallback) {
this.idleManager?.registerCallback(async () => {
await this.logout();
});
}
}
async logout(options) {
await this.setConnectedUserToStorage(undefined);
this.idleManager?.exit();
this.idleManager = undefined;
await this.options.onLogout?.();
if (options?.returnTo) {
try {
window.history.pushState({}, "", options.returnTo);
}
catch (e) {
window.location.href = options.returnTo;
}
}
}
async setConnectedUser(user) {
if (!user)
this.connectedUser = undefined;
else {
let subAccount;
if (user.subAccount) {
const subAccountOrError = SubAccount.fromBytes(new Uint8Array(user.subAccount));
if (typeof subAccountOrError === typeof Error) {
throw subAccount;
}
subAccount = subAccountOrError;
}
this.connectedUser = {
principal: Principal.from(user.owner),
subAccount,
};
}
}
async setConnectedUserToStorage(user) {
if (!user) {
await this.storage.remove(STORAGE_CONNECTED_OWNER_KEY);
await this.storage.remove(STORAGE_CONNECTED_SUBACCOUNT_KEY);
localStorage.removeItem("connected");
this.setConnectedUser(undefined);
return;
}
await this.storage.set(STORAGE_CONNECTED_OWNER_KEY, user.owner);
localStorage.setItem("connected", "1");
if (user.subAccount)
await this.storage.set(STORAGE_CONNECTED_SUBACCOUNT_KEY, new TextDecoder().decode(user.subAccount));
this.setConnectedUser({
owner: user.owner,
subAccount: user.subAccount,
});
}
// sync method to check if it's needed to check authorization reading from async storage
static shouldCheckIsUserConnected() {
return !!localStorage.getItem("connected");
}
async getConnectedUserFromStorage() {
const owner = await this.storage.get(STORAGE_CONNECTED_OWNER_KEY);
if (!owner)
return;
const subAccount = await this.storage.get(STORAGE_CONNECTED_SUBACCOUNT_KEY);
return {
owner: owner.toString(),
subAccount: subAccount
? new TextEncoder().encode(subAccount.toString()).buffer
: undefined,
};
}
get crypto() {
return this.options.crypto ?? globalThis.crypto;
}
}
const ED25519_KEY_LABEL = "Ed25519";
var DelegationType;
(function (DelegationType) {
DelegationType["ACCOUNT"] = "ACCOUNT";
DelegationType["RELYING_PARTY"] = "RELYING_PARTY";
})(DelegationType || (DelegationType = {}));
const NANOS_IN_MILLIS = BigInt(1000000);
class DelegationSignerClient extends SignerClient {
identity;
baseIdentity;
targets;
maxTimeToLive;
expirationManager;
constructor(options, identity, baseIdentity, targets, maxTimeToLive = BigInt(DEFAULT_MAX_TIME_TO_LIVE)) {
// TODO for delegation use delegation expiration as idle timeout
super(options);
this.identity = identity;
this.baseIdentity = baseIdentity;
this.targets = targets;
this.maxTimeToLive = maxTimeToLive;
}
static async create(options) {
const storage = options.storage ?? new IdbStorage();
let baseIdentity = options.identity;
let identity = new AnonymousIdentity();
if (this.shouldCheckIsUserConnected() && !baseIdentity) {
baseIdentity = await getIdentity(STORAGE_KEY, storage);
}
if (!baseIdentity) {
const createdBaseIdentity = await (!options?.keyType || options?.keyType === ED25519_KEY_LABEL
? Ed25519KeyIdentity.generate(crypto.getRandomValues(new Uint8Array(32)))
: ECDSAKeyIdentity.generate());
baseIdentity = createdBaseIdentity;
}
if (this.shouldCheckIsUserConnected()) {
const delegationChain = await getDelegationChain(STORAGE_KEY, storage);
const delegationValid = baseIdentity && delegationChain && isDelegationValid(delegationChain);
identity = delegationValid
? DelegationSignerClient.createIdentity(baseIdentity, delegationChain)
: new AnonymousIdentity();
const signerClient = new DelegationSignerClient(options, identity, baseIdentity, options.targets, options.maxTimeToLive);
if (delegationValid) {
signerClient.initExpirationManager(delegationChain);
const storageConnectedUser = await signerClient.getConnectedUserFromStorage();
await signerClient.setConnectedUser(storageConnectedUser);
}
else {
await signerClient.setConnectedUserToStorage(undefined);
await signerClient.setConnectedUser(undefined);
}
return signerClient;
}
const signerClient = new DelegationSignerClient(options, identity, baseIdentity, options.targets, options.maxTimeToLive);
return signerClient;
}
static createIdentity(baseIdentity, delegationChain) {
if (baseIdentity instanceof PartialIdentity) {
return PartialDelegationIdentity.fromDelegation(baseIdentity, delegationChain);
}
return DelegationIdentity.fromDelegation(baseIdentity, delegationChain);
}
async login() {
const params = this.options.derivationOrigin
? {
icrc95DerivationOrigin: this.options.derivationOrigin,
}
: {};
const delegationChainResponse = await this.options.signer.sendRequest({
id: this.crypto.randomUUID(),
jsonrpc: "2.0",
method: "icrc34_delegation",
params: {
...params,
publicKey: toBase64(this.baseIdentity.getPublicKey().toDer()),
targets: this.targets,
maxTimeToLive: this.maxTimeToLive === undefined ? undefined : String(this.maxTimeToLive),
},
});
if ("error" in delegationChainResponse) {
throw Error(delegationChainResponse.error.message);
}
const delegationChain = DelegationChain.fromDelegations(delegationChainResponse.result.signerDelegation.map((delegation) => {
return {
delegation: new Delegation(fromBase64(delegation.delegation.pubkey), BigInt(delegation.delegation.expiration), delegation.delegation.targets?.map((principal) => Principal.fromText(principal))),
signature: fromBase64(delegation.signature),
};
}), fromBase64(delegationChainResponse.result.publicKey));
if (this.baseIdentity instanceof Ed25519KeyIdentity ||
this.baseIdentity instanceof ECDSAKeyIdentity) {
await setIdentity(STORAGE_KEY, this.baseIdentity, this.storage);
}
await setDelegationChain(STORAGE_KEY, delegationChain, this.storage);
this.identity = DelegationSignerClient.createIdentity(this.baseIdentity, delegationChain);
await this.setConnectedUserToStorage({ owner: this.identity.getPrincipal().toString() });
if (!this.options?.idleOptions?.disableIdle && !this.idleManager) {
this.idleManager = new IdleManager(this.options.idleOptions);
this.registerDefaultIdleCallback();
}
return this.initExpirationManager(delegationChain);
}
initExpirationManager(delegationChain) {
if (!this.expirationManager) {
const delegationExpirationInMillis = Number(delegationChain.delegations.reduce((acc, value) => {
const bigIntValue = BigInt(value.delegation.expiration) / NANOS_IN_MILLIS;
return bigIntValue > acc ? bigIntValue : acc;
}, BigInt(delegationChain.delegations[0].delegation.expiration) / NANOS_IN_MILLIS)) - Date.now();
this.expirationManager = new TimeoutManager({ timeout: delegationExpirationInMillis });
this.expirationManager?.registerCallback(async () => {
await this.logout();
});
}
}
async logout(options) {
await Promise.all([
removeIdentity(STORAGE_KEY, this.storage),
removeDelegationChain(STORAGE_KEY, this.storage),
]);
this.identity = new AnonymousIdentity();
return super.logout(options);
}
getIdentity() {
return this.identity;
}
async getDelegationType() {
if (!this.connectedUser)
throw new Error("Not authorized");
const delegationChain = await getDelegationChain(STORAGE_KEY, this.storage);
if (!delegationChain)
throw new Error("Not authorized");
return delegationChain.delegations[0].delegation.targets?.length
? DelegationType.ACCOUNT
: DelegationType.RELYING_PARTY;
}
async getDelegation() {
const chain = await getDelegationChain(STORAGE_KEY, this.storage);
return chain?.delegations[0];
}
}
class AccountsSignerClient extends SignerClient {
static async create(options) {
const signerClient = new AccountsSignerClient(options);
if (SignerClient.shouldCheckIsUserConnected()) {
const storageConnectedUser = await signerClient.getConnectedUserFromStorage();
await signerClient.setConnectedUser(storageConnectedUser);
}
return signerClient;
}
async login() {
// get and transform accounts from signer
const params = this.options.derivationOrigin
? {
params: {
icrc95DerivationOrigin: this.options.derivationOrigin,
},
}
: {};
const accountsResponse = await this.options.signer.sendRequest({
method: "icrc27_accounts",
id: this.crypto.randomUUID(),
jsonrpc: "2.0",
...params,
});
if ("error" in accountsResponse) {
throw Error(accountsResponse.error.message);
}
const accounts = accountsResponse.result.accounts.map(({ owner, subaccount }) => {
return {
owner: Principal.fromText(owner),
subaccount: subaccount === undefined ? undefined : fromBase64(subaccount),
};
});
await this.setAccounts(accounts);
const account = accounts[0];
if (!account.subaccount) {
if (!this.options?.idleOptions?.disableIdle && !this.idleManager) {
this.idleManager = new IdleManager(this.options.idleOptions);
this.registerDefaultIdleCallback();
}
await this.setConnectedUserToStorage({ owner: account.owner.toString() });
return;
}
await this.setConnectedUserToStorage({
owner: account.owner.toString(),
subAccount: account.subaccount,
});
if (!this.options?.idleOptions?.disableIdle && !this.idleManager) {
this.idleManager = new IdleManager(this.options.idleOptions);
this.registerDefaultIdleCallback();
}
}
async logout(options) {
await this.storage.remove(`accounts-${STORAGE_KEY}`);
return super.logout(options);
}
async setAccounts(accounts) {
return this.storage.set(`accounts-${STORAGE_KEY}`, JSON.stringify(accounts.map((acc) => ({
owner: acc.owner.toString(),
subaccount: acc.subaccount && new TextDecoder().decode(acc.subaccount),
}))));
}
async getAccounts() {
const storageData = await this.storage.get(`accounts-${STORAGE_KEY}`);
if (!storageData || typeof storageData !== "string")
return;
return JSON.parse(storageData).map(({ owner, subaccount }) => {
let subAccount;
if (subaccount) {
const subAccountOrError = SubAccount.fromBytes(new Uint8Array(new TextEncoder().encode(subaccount)));
if (typeof subAccountOrError === typeof Error) {
throw subAccount;
}
subAccount = subAccountOrError;
}
return {
principal: Principal.from(owner),
subAccount,
};
});
}
}
var TransportType;
(function (TransportType) {
TransportType[TransportType["NEW_TAB"] = 0] = "NEW_TAB";
TransportType[TransportType["EXTENSION"] = 1] = "EXTENSION";
TransportType[TransportType["INTERNET_IDENTITY"] = 2] = "INTERNET_IDENTITY";
TransportType[TransportType["STOIC"] = 3] = "STOIC";
})(TransportType || (TransportType = {}));
const NFIDW = {
id: "NFIDW",
description: "Quickly sign in or create an anonymous, self-sovereign wallet with your email address or passkey.",
providerUrl: "https://nfid.one/rpc",
transportType: TransportType.NEW_TAB,
label: "NFID Wallet",
icon: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjQiIGhlaWdodD0iNjQiIHZpZXdCb3g9IjAgMCA2NCA2NCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNS45MDIyIDMuMTU2MjlDMTYuNzcxNCAzLjA2MzYzIDE3LjQwMDggMi4yODM5OCAxNy4zMDgxIDEuNDE0ODlDMTcuMjE1NSAwLjU0NTgwOSAxNi40MzU4IC0wLjA4MzYwOTkgMTUuNTY2NyAwLjAwOTA0OTQ2TDEyLjMzNDUgMC4zNTM2MzNDMTAuNjc4NiAwLjUzMDE2NSA5LjM1MDQ2IDAuNjcxNzUxIDguMjcxOCAwLjg2NzMwNkM3LjE2MDYgMS4wNjg3NiA2LjIwODI3IDEuMzQ0MTQgNS4zMjM3OCAxLjgzOTgxQzMuODg3NzMgMi42NDQ1NyAyLjY5NzE5IDMuODIzODUgMS44Nzk0NCA1LjI1MTk2QzEuMzc1NjggNi4xMzE3MyAxLjA5MjA0IDcuMDgxMTIgMC44ODExODUgOC4xODk2MUMwLjY3NjUzNSA5LjI2NTQ5IDAuNTIzODkzIDEwLjU5MSAwLjMzMzYyMSAxMi4yNDMyTDAuMzI1NDI0IDEyLjMxNDRMMC4wMDgwNjAwNiAxNS40NzA0Qy0wLjA3OTM4NzUgMTYuMzQgMC41NTQ3MjYgMTcuMTE1OSAxLjQyNDM5IDE3LjIwMzRDMi4yOTQwNiAxNy4yOTA4IDMuMDY5OTUgMTYuNjU2NyAzLjE1NzQgMTUuNzg3MUwzLjQ3MjQ4IDEyLjY1MzhDMy42NzA1NCAxMC45MzQgMy44MTA2NiA5LjcyNzMgMy45OTA2NiA4Ljc4MTAzQzQuMTY3MzEgNy44NTIzNSA0LjM2NDQ5IDcuMjgxODEgNC42MjYyNiA2LjgyNDY3QzUuMTU5MDEgNS44OTQyNyA1LjkzNDg3IDUuMTI1NTkgNi44NzEyMSA0LjYwMDg2QzcuMzMxNTEgNC4zNDI5MSA3LjkwNDg2IDQuMTUwNTEgOC44MzY0NiAzLjk4MTYxQzkuNzg3NjYgMy44MDkxNiAxMS4wMDA1IDMuNjc4ODggMTIuNzI5OSAzLjQ5NDVMMTUuOTAyMiAzLjE1NjI5Wk00Ni42OTE5IDEuNDE0ODlDNDYuNTk5MiAyLjI4Mzk4IDQ3LjIyODYgMy4wNjM2MyA0OC4wOTc4IDMuMTU2MjlMNTEuMjcwMSAzLjQ5NDVDNTIuOTk5NSAzLjY3ODg4IDU0LjIxMjMgMy44MDkxNiA1NS4xNjM1IDMuOTgxNjFDNTYuMDk1MSA0LjE1MDUxIDU2LjY2ODUgNC4zNDI5MSA1Ny4xMjg4IDQuNjAwODZDNTguMDY1MSA1LjEyNTU5IDU4Ljg0MSA1Ljg5NDI3IDU5LjM3MzcgNi44MjQ2N0M1OS42MzU1IDcuMjgxODEgNTkuODMyNyA3Ljg1MjM1IDYwLjAwOTMgOC43ODEwM0M2MC4xODkzIDkuNzI3MyA2MC4zMjk1IDEwLjkzNCA2MC41Mjc1IDEyLjY1MzhMNjAuODQyNiAxNS43ODcxQzYwLjkzIDE2LjY1NjcgNjEuNzA1OSAxNy4yOTA4IDYyLjU3NTYgMTcuMjAzNEM2My40NDUzIDE3LjExNTkgNjQuMDc5NCAxNi4zNCA2My45OTE5IDE1LjQ3MDRMNjMuNjc0NiAxMi4zMTQ0TDYzLjY2NjQgMTIuMjQzMkM2My40NzYxIDEwLjU5MSA2My4zMjM1IDkuMjY1NDkgNjMuMTE4OCA4LjE4OTYxQzYyLjkwOCA3LjA4MTEyIDYyLjYyNDMgNi4xMzE3MyA2Mi4xMjA2IDUuMjUxOTZDNjEuMzAyOCAzLjgyMzg1IDYwLjExMjMgMi42NDQ1NyA1OC42NzYyIDEuODM5ODFDNTcuNzkxNyAxLjM0NDE0IDU2LjgzOTQgMS4wNjg3NiA1NS43MjgyIDAuODY3MzA2QzU0LjY0OTUgMC42NzE3NTEgNTMuMzIxNCAwLjUzMDE2NSA1MS42NjU1IDAuMzUzNjMzTDQ4LjQzMzMgMC4wMDkwNDk0NkM0Ny41NjQyIC0wLjA4MzYwOTkgNDYuNzg0NSAwLjU0NTgwOSA0Ni42OTE5IDEuNDE0ODlaTTQ2LjY5MTkgNjIuNTg1MUM0Ni41OTkyIDYxLjcxNiA0Ny4yMjg2IDYwLjkzNjQgNDguMDk3OCA2MC44NDM3TDUxLjI3MDEgNjAuNTA1NUM1Mi45OTk1IDYwLjMyMTEgNTQuMjEyMyA2MC4xOTA4IDU1LjE2MzUgNjAuMDE4NEM1Ni4wOTUxIDU5Ljg0OTUgNTYuNjY4NSA1OS42NTcxIDU3LjEyODggNTkuMzk5MUM1OC4wNjUxIDU4Ljg3NDQgNTguODQxIDU4LjEwNTcgNTkuMzczNyA1Ny4xNzUzQzU5LjYzNTUgNTYuNzE4MiA1OS44MzI3IDU2LjE0NzYgNjAuMDA5MyA1NS4yMTlDNjAuMTg5MyA1NC4yNzI3IDYwLjMyOTUgNTMuMDY2IDYwLjUyNzUgNTEuMzQ2Mkw2MC44NDI2IDQ4LjIxMjlDNjAuOTMgNDcuMzQzMyA2MS43MDU5IDQ2LjcwOTIgNjIuNTc1NiA0Ni43OTY2QzYzLjQ0NTMgNDYuODg0MSA2NC4wNzk0IDQ3LjY2IDYzLjk5MTkgNDguNTI5Nkw2My42NzQ2IDUxLjY4NTZMNjMuNjY2NCA1MS43NTY4QzYzLjQ3NjEgNTMuNDA5IDYzLjMyMzUgNTQuNzM0NSA2My4xMTg4IDU1LjgxMDRDNjIuOTA4IDU2LjkxODkgNjIuNjI0MyA1Ny44NjgzIDYyLjEyMDYgNTguNzQ4QzYxLjMwMjggNjAuMTc2MiA2MC4xMTIzIDYxLjM1NTQgNTguNjc2MiA2Mi4xNjAyQzU3Ljc5MTcgNjIuNjU1OSA1Ni44Mzk0IDYyLjkzMTIgNTUuNzI4MiA2My4xMzI3QzU0LjY0OTYgNjMuMzI4MiA1My4zMjE2IDYzLjQ2OTggNTEuNjY1OCA2My42NDYzTDUxLjY2NTYgNjMuNjQ2M0w1MS42NjU1IDYzLjY0NjRMNTEuNjY1NSA2My42NDY0TDQ4LjQzMzMgNjMuOTkxQzQ3LjU2NDIgNjQuMDgzNiA0Ni43ODQ1IDYzLjQ1NDIgNDYuNjkxOSA2Mi41ODUxWk0xNy4zMDgxIDYyLjU4NTZDMTcuNDAwOCA2MS43MTY1IDE2Ljc3MTQgNjAuOTM2OSAxNS45MDIyIDYwLjg0NDJMMTIuNzI5OSA2MC41MDZDMTEuMDAwNSA2MC4zMjE2IDkuNzg3NjYgNjAuMTkxMyA4LjgzNjQ2IDYwLjAxODlDNy45MDQ4NiA1OS44NSA3LjMzMTUxIDU5LjY1NzYgNi44NzEyMSA1OS4zOTk2QzUuOTM0ODcgNTguODc0OSA1LjE1OTAxIDU4LjEwNjIgNC42MjYyNiA1Ny4xNzU4QzQuMzY0NDkgNTYuNzE4NyA0LjE2NzMxIDU2LjE0ODEgMy45OTA2NiA1NS4yMTk1QzMuODEwNjYgNTQuMjczMiAzLjY3MDU0IDUzLjA2NjUgMy40NzI0OCA1MS4zNDY3TDMuMTU3NCA0OC4yMTM0QzMuMDY5OTUgNDcuMzQzOCAyLjI5NDA2IDQ2LjcwOTcgMS40MjQzOSA0Ni43OTcxQzAuNTU0NzI2IDQ2Ljg4NDYgLTAuMDc5Mzg3NSA0Ny42NjA0IDAuMDA4MDYwMDYgNDguNTMwMUwwLjMyNTQyNCA1MS42ODYxTDAuMzMzNjIxIDUxLjc1NzNDMC41MjM4OTMgNTMuNDA5NSAwLjY3NjUzNSA1NC43MzUgMC44ODExODUgNTUuODEwOUMxLjA5MjA0IDU2LjkxOTQgMS4zNzU2OCA1Ny44Njg4IDEuODc5NDQgNTguNzQ4NUMyLjY5NzE5IDYwLjE3NjYgMy44ODc3MyA2MS4zNTU5IDUuMzIzNzggNjIuMTYwN0M2LjIwODI3IDYyLjY1NjMgNy4xNjA2IDYyLjkzMTcgOC4yNzE4IDYzLjEzMzJDOS4zNTA0NCA2My4zMjg3IDEwLjY3ODYgNjMuNDcwMyAxMi4zMzQ1IDYzLjY0NjhMMTIuMzM0NSA2My42NDY5TDE1LjU2NjcgNjMuOTkxNEMxNi40MzU4IDY0LjA4NDEgMTcuMjE1NSA2My40NTQ3IDE3LjMwODEgNjIuNTg1NlpNMTYuNDUxMiAxOS43OTU0QzE1LjY5NTUgMTkuNzk1NCAxNS4wODI4IDIwLjQwODEgMTUuMDgyOCAyMS4xNjM4VjQzLjI5NzJDMTUuMDgyOCA0NC4wNTMgMTUuNjk1NSA0NC42NjU2IDE2LjQ1MTIgNDQuNjY1NkgyMC43NDk0QzIxLjUwNTIgNDQuNjY1NiAyMi4xMTc4IDQ0LjA1MyAyMi4xMTc4IDQzLjI5NzJWMjEuMTYzOEMyMi4xMTc4IDIwLjQwODEgMjEuNTA1MiAxOS43OTU0IDIwLjc0OTQgMTkuNzk1NEgxNi40NTEyWk0yOC4xMDgyIDE5Ljc5NTRDMjcuMzUyNSAxOS43OTU0IDI2LjczOTggMjAuNDA4MSAyNi43Mzk4IDIxLjE2MzhWNDMuMjk3MkMyNi43Mzk4IDQ0LjA1MyAyNy4zNTI1IDQ0LjY2NTYgMjguMTA4MiA0NC42NjU2SDM4LjUwMDRDNDEuMjI0NCA0NC42NjU2IDQzLjY0MDUgNDQuMTU2NCA0NS43NDg3IDQzLjEzNzlDNDcuODU2OCA0Mi4xMTk0IDQ5LjQ5MTIgNDAuNjc0NiA1MC42NTE5IDM4LjgwMzRDNTEuODEyNSAzNi45MzIyIDUyLjM5MjkgMzQuNzQxMiA1Mi4zOTI5IDMyLjIzMDVDNTIuMzkyOSAyOS43MTk4IDUxLjgxMjUgMjcuNTI4OSA1MC42NTE5IDI1LjY1NzdDNDkuNDkxMiAyMy43ODY1IDQ3Ljg1NjggMjIuMzQxNyA0NS43NDg3IDIxLjMyMzJDNDMuNjQwNSAyMC4zMDQ3IDQxLjIyNDQgMTkuNzk1NCAzOC41MDA0IDE5Ljc5NTRIMjguMTA4MlpNNDMuMzMyNiAzNy4yNDAxQzQyLjA1MzUgMzguNDQ4MSA0MC4zNDggMzkuMDUyMSAzOC4yMTYyIDM5LjA1MjFIMzQuMTg1NEMzMy45NTg3IDM5LjA1MjEgMzMuNzc0OSAzOC44NjgzIDMzLjc3NDkgMzguNjQxNlYyNS44MTk1QzMzLjc3NDkgMjUuNTkyOCAzMy45NTg3IDI1LjQwOSAzNC4xODU0IDI1LjQwOUgzOC4yMTYyQzQwLjM0OCAyNS40MDkgNDIuMDUzNSAyNi4wMTMgNDMuMzMyNiAyNy4yMjFDNDQuNjM1NCAyOC40Mjg5IDQ1LjI4NjggMzAuMDk4OCA0NS4yODY4IDMyLjIzMDVDNDUuMjg2OCAzNC4zNjIzIDQ0LjYzNTQgMzYuMDMyMSA0My4zMzI2IDM3LjI0MDFaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfODAzODBfNTQpIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfODAzODBfNTQiIHgxPSIwLjc2NTgxMiIgeTE9Ii0yLjcwNDk2ZS0wNyIgeDI9IjYzLjU0MTciIHkyPSI2NC4yNzkzIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiMwMEE2OTUiLz4KPHN0b3Agb2Zmc2V0PSIwLjUiIHN0b3AtY29sb3I9IiMwMTg0NzciLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDA2RjY0Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg==",
};
const MockedSigner = {
id: "MockedSigner",
providerUrl: "https://uimp7-mqaaa-aaaag-qc5ka-cai.icp0.io",
transportType: TransportType.NEW_TAB,
label: "Mocked Signer Wallet",
icon: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjQiIGhlaWdodD0iNjQiIHZpZXdCb3g9IjAgMCA2NCA2NCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNS45MDIyIDMuMTU2MjlDMTYuNzcxNCAzLjA2MzYzIDE3LjQwMDggMi4yODM5OCAxNy4zMDgxIDEuNDE0ODlDMTcuMjE1NSAwLjU0NTgwOSAxNi40MzU4IC0wLjA4MzYwOTkgMTUuNTY2NyAwLjAwOTA0OTQ2TDEyLjMzNDUgMC4zNTM2MzNDMTAuNjc4NiAwLjUzMDE2NSA5LjM1MDQ2IDAuNjcxNzUxIDguMjcxOCAwLjg2NzMwNkM3LjE2MDYgMS4wNjg3NiA2LjIwODI3IDEuMzQ0MTQgNS4zMjM3OCAxLjgzOTgxQzMuODg3NzMgMi42NDQ1NyAyLjY5NzE5IDMuODIzODUgMS44Nzk0NCA1LjI1MTk2QzEuMzc1NjggNi4xMzE3MyAxLjA5MjA0IDcuMDgxMTIgMC44ODExODUgOC4xODk2MUMwLjY3NjUzNSA5LjI2NTQ5IDAuNTIzODkzIDEwLjU5MSAwLjMzMzYyMSAxMi4yNDMyTDAuMzI1NDI0IDEyLjMxNDRMMC4wMDgwNjAwNiAxNS40NzA0Qy0wLjA3OTM4NzUgMTYuMzQgMC41NTQ3MjYgMTcuMTE1OSAxLjQyNDM5IDE3LjIwMzRDMi4yOTQwNiAxNy4yOTA4IDMuMDY5OTUgMTYuNjU2NyAzLjE1NzQgMTUuNzg3MUwzLjQ3MjQ4IDEyLjY1MzhDMy42NzA1NCAxMC45MzQgMy44MTA2NiA5LjcyNzMgMy45OTA2NiA4Ljc4MTAzQzQuMTY3MzEgNy44NTIzNSA0LjM2NDQ5IDcuMjgxODEgNC42MjYyNiA2LjgyNDY3QzUuMTU5MDEgNS44OTQyNyA1LjkzNDg3IDUuMTI1NTkgNi44NzEyMSA0LjYwMDg2QzcuMzMxNTEgNC4zNDI5MSA3LjkwNDg2IDQuMTUwNTEgOC44MzY0NiAzLjk4MTYxQzkuNzg3NjYgMy44MDkxNiAxMS4wMDA1IDMuNjc4ODggMTIuNzI5OSAzLjQ5NDVMMTUuOTAyMiAzLjE1NjI5Wk00Ni42OTE5IDEuNDE0ODlDNDYuNTk5MiAyLjI4Mzk4IDQ3LjIyODYgMy4wNjM2MyA0OC4wOTc4IDMuMTU2MjlMNTEuMjcwMSAzLjQ5NDVDNTIuOTk5NSAzLjY3ODg4IDU0LjIxMjMgMy44MDkxNiA1NS4xNjM1IDMuOTgxNjFDNTYuMDk1MSA0LjE1MDUxIDU2LjY2ODUgNC4zNDI5MSA1Ny4xMjg4IDQuNjAwODZDNTguMDY1MSA1LjEyNTU5IDU4Ljg0MSA1Ljg5NDI3IDU5LjM3MzcgNi44MjQ2N0M1OS42MzU1IDcuMjgxODEgNTkuODMyNyA3Ljg1MjM1IDYwLjAwOTMgOC43ODEwM0M2MC4xODkzIDkuNzI3MyA2MC4zMjk1IDEwLjkzNCA2MC41Mjc1IDEyLjY1MzhMNjAuODQyNiAxNS43ODcxQzYwLjkzIDE2LjY1NjcgNjEuNzA1OSAxNy4yOTA4IDYyLjU3NTYgMTcuMjAzNEM2My40NDUzIDE3LjExNTkgNjQuMDc5NCAxNi4zNCA2My45OTE5IDE1LjQ3MDRMNjMuNjc0NiAxMi4zMTQ0TDYzLjY2NjQgMTIuMjQzMkM2My40NzYxIDEwLjU5MSA2My4zMjM1IDkuMjY1NDkgNjMuMTE4OCA4LjE4OTYxQzYyLjkwOCA3LjA4MTEyIDYyLjYyNDMgNi4xMzE3MyA2Mi4xMjA2IDUuMjUxOTZDNjEuMzAyOCAzLjgyMzg1IDYwLjExMjMgMi42NDQ1NyA1OC42NzYyIDEuODM5ODFDNTcuNzkxNyAxLjM0NDE0IDU2LjgzOTQgMS4wNjg3NiA1NS43MjgyIDAuODY3MzA2QzU0LjY0OTUgMC42NzE3NTEgNTMuMzIxNCAwLjUzMDE2NSA1MS42NjU1IDAuMzUzNjMzTDQ4LjQzMzMgMC4wMDkwNDk0NkM0Ny41NjQyIC0wLjA4MzYwOTkgNDYuNzg0NSAwLjU0NTgwOSA0Ni42OTE5IDEuNDE0ODlaTTQ2LjY5MTkgNjIuNTg1MUM0Ni41OTkyIDYxLjcxNiA0Ny4yMjg2IDYwLjkzNjQgNDguMDk3OCA2MC44NDM3TDUxLjI3MDEgNjAuNTA1NUM1Mi45OTk1IDYwLjMyMTEgNTQuMjEyMyA2MC4xOTA4IDU1LjE2MzUgNjAuMDE4NEM1Ni4wOTUxIDU5Ljg0OTUgNTYuNjY4NSA1OS42NTcxIDU3LjEyODggNTkuMzk5MUM1OC4wNjUxIDU4Ljg3NDQgNTguODQxIDU4LjEwNTcgNTkuMzczNyA1Ny4xNzUzQzU5LjYzNTUgNTYuNzE4MiA1OS44MzI3IDU2LjE0NzYgNjAuMDA5MyA1NS4yMTlDNjAuMTg5MyA1NC4yNzI3IDYwLjMyOTUgNTMuMDY2IDYwLjUyNzUgNTEuMzQ2Mkw2MC44NDI2IDQ4LjIxMjlDNjAuOTMgNDcuMzQzMyA2MS43MDU5IDQ2LjcwOTIgNjIuNTc1NiA0Ni43OTY2QzYzLjQ0NTMgNDYuODg0MSA2NC4wNzk0IDQ3LjY2IDYzLjk5MTkgNDguNTI5Nkw2My42NzQ2IDUxLjY4NTZMNjMuNjY2NCA1MS43NTY4QzYzLjQ3NjEgNTMuNDA5IDYzLjMyMzUgNTQuNzM0NSA2My4xMTg4IDU1LjgxMDRDNjIuOTA4IDU2LjkxODkgNjIuNjI0MyA1Ny44NjgzIDYyLjEyMDYgNTguNzQ4QzYxLjMwMjggNjAuMTc2MiA2MC4xMTIzIDYxLjM1NTQgNTguNjc2MiA2Mi4xNjAyQzU3Ljc5MTcgNjIuNjU1OSA1Ni44Mzk0IDYyLjkzMTIgNTUuNzI4MiA2My4xMzI3QzU0LjY0OTYgNjMuMzI4MiA1My4zMjE2IDYzLjQ2OTggNTEuNjY1OCA2My42NDYzTDUxLjY2NTYgNjMuNjQ2M0w1MS42NjU1IDYzLjY0NjRMNTEuNjY1NSA2My42NDY0TDQ4LjQzMzMgNjMuOTkxQzQ3LjU2NDIgNjQuMDgzNiA0Ni43ODQ1IDYzLjQ1NDIgNDYuNjkxOSA2Mi41ODUxWk0xNy4zMDgxIDYyLjU4NTZDMTcuNDAwOCA2MS43MTY1IDE2Ljc3MTQgNjAuOTM2OSAxNS45MDIyIDYwLjg0NDJMMTIuNzI5OSA2MC41MDZDMTEuMDAwNSA2MC4zMjE2IDkuNzg3NjYgNjAuMTkxMyA4LjgzNjQ2IDYwLjAxODlDNy45MDQ4NiA1OS44NSA3LjMzMTUxIDU5LjY1NzYgNi44NzEyMSA1OS4zOTk2QzUuOTM0ODcgNTguODc0OSA1LjE1OTAxIDU4LjEwNjIgNC42MjYyNiA1Ny4xNzU4QzQuMzY0NDkgNTYuNzE4NyA0LjE2NzMxIDU2LjE0ODEgMy45OTA2NiA1NS4yMTk1QzMuODEwNjYgNTQuMjczMiAzLjY3MDU0IDUzLjA2NjUgMy40NzI0OCA1MS4zNDY3TDMuMTU3NCA0OC4yMTM0QzMuMDY5OTUgNDcuMzQzOCAyLjI5NDA2IDQ2LjcwOTcgMS40MjQzOSA0Ni43OTcxQzAuNTU0NzI2IDQ2Ljg4NDYgLTAuMDc5Mzg3NSA0Ny42NjA0IDAuMDA4MDYwMDYgNDguNTMwMUwwLjMyNTQyNCA1MS42ODYxTDAuMzMzNjIxIDUxLjc1NzNDMC41MjM4OTMgNTMuNDA5NSAwLjY3NjUzNSA1NC43MzUgMC44ODExODUgNTUuODEwOUMxLjA5MjA0IDU2LjkxOTQgMS4zNzU2OCA1Ny44Njg4IDEuODc5NDQgNTguNzQ4NUMyLjY5NzE5IDYwLjE3NjYgMy44ODc3MyA2MS4zNTU5IDUuMzIzNzggNjIuMTYwN0M2LjIwODI3IDYyLjY1NjMgNy4xNjA2IDYyLjkzMTcgOC4yNzE4IDYzLjEzMzJDOS4zNTA0NCA2My4zMjg3IDEwLjY3ODYgNjMuNDcwMyAxMi4zMzQ1IDYzLjY0NjhMMTIuMzM0NSA2My42NDY5TDE1LjU2NjcgNjMuOTkxNEMxNi40MzU4IDY0LjA4NDEgMTcuMjE1NSA2My40NTQ3IDE3LjMwODEgNjIuNTg1NlpNMTYuNDUxMiAxOS43OTU0QzE1LjY5NTUgMTkuNzk1NCAxNS4wODI4IDIwLjQwODEgMTUuMDgyOCAyMS4xNjM4VjQzLjI5NzJDMTUuMDgyOCA0NC4wNTMgMTUuNjk1NSA0NC42NjU2IDE2LjQ1MTIgNDQuNjY1NkgyMC43NDk0QzIxLjUwNTIgNDQuNjY1NiAyMi4xMTc4IDQ0LjA1MyAyMi4xMTc4IDQzLjI5NzJWMjEuMTYzOEMyMi4xMTc4IDIwLjQwODEgMjEuNTA1MiAxOS43OTU0IDIwLjc0OTQgMTkuNzk1NEgxNi40NTEyWk0yOC4xMDgyIDE5Ljc5NTRDMjcuMzUyNSAxOS43OTU0IDI2LjczOTggMjAuNDA4MSAyNi43Mzk4IDIxLjE2MzhWNDMuMjk3MkMyNi43Mzk4IDQ0LjA1MyAyNy4zNTI1IDQ0LjY2NTYgMjguMTA4MiA0NC42NjU2SDM4LjUwMDRDNDEuMjI0NCA0NC42NjU2IDQzLjY0MDUgNDQuMTU2NCA0NS43NDg3IDQzLjEzNzlDNDcuODU2OCA0Mi4xMTk0IDQ5LjQ5MTIgNDAuNjc0NiA1MC42NTE5IDM4LjgwMzRDNTEuODEyNSAzNi45MzIyIDUyLjM5MjkgMzQuNzQxMiA1Mi4zOTI5IDMyLjIzMDVDNTIuMzkyOSAyOS43MTk4IDUxLjgxMjUgMjcuNTI4OSA1MC42NTE5IDI1LjY1NzdDNDkuNDkxMiAyMy43ODY1IDQ3Ljg1NjggMjIuMzQxNyA0NS43NDg3IDIxLjMyMzJDNDMuNjQwNSAyMC4zMDQ3IDQxLjIyNDQgMTkuNzk1NCAzOC41MDA0IDE5Ljc5NTRIMjguMTA4MlpNNDMuMzMyNiAzNy4yNDAxQzQyLjA1MzUgMzguNDQ4MSA0MC4zNDggMzkuMDUyMSAzOC4yMTYyIDM5LjA1MjFIMzQuMTg1NEMzMy45NTg3IDM5LjA1MjEgMzMuNzc0OSAzOC44NjgzIDMzLjc3NDkgMzguNjQxNlYyNS44MTk1QzMzLjc3NDkgMjUuNTkyOCAzMy45NTg3IDI1LjQwOSAzNC4xODU0IDI1LjQwOUgzOC4yMTYyQzQwLjM0OCAyNS40MDkgNDIuMDUzNSAyNi4wMTMgNDMuMzMyNiAyNy4yMjFDNDQuNjM1NCAyOC40Mjg5IDQ1LjI4NjggMzAuMDk4OCA0NS4yODY4IDMyLjIzMDVDNDUuMjg2OCAzNC4zNjIzIDQ0LjYzNTQgMzYuMDMyMSA0My4zMzI2IDM3LjI0MDFaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfODAzODBfNTQpIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfODAzODBfNTQiIHgxPSIwLjc2NTgxMiIgeTE9Ii0yLjcwNDk2ZS0wNyIgeDI9IjYzLjU0MTciIHkyPSI2NC4yNzkzIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiMwMEE2OTUiLz4KPHN0b3Agb2Zmc2V0PSIwLjUiIHN0b3AtY29sb3I9IiMwMTg0NzciLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDA2RjY0Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg==",
};
const InternetIdentity = {
id: "InternetIdentity",
providerUrl: "https://id.ai/?feature_flag_guided_upgrade=true",
transportType: TransportType.INTERNET_IDENTITY,
label: "Internet Identity",
icon: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI0LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAzNTguOCAxNzkuOCIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzU4LjggMTc5Ljg7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDp1cmwoI1NWR0lEXzFfKTt9Cgkuc3Qxe2ZpbGw6dXJsKCNTVkdJRF8yXyk7fQoJLnN0MntmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiMyOUFCRTI7fQo8L3N0eWxlPgo8bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzFfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIyNC43ODUzIiB5MT0iMjU3Ljc1MzYiIHgyPSIzNDguMDY2MyIgeTI9IjEzMy40NTgxIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDEgMCAwIC0xIDAgMjcyKSI+Cgk8c3RvcCAgb2Zmc2V0PSIwLjIxIiBzdHlsZT0ic3RvcC1jb2xvcjojRjE1QTI0Ii8+Cgk8c3RvcCAgb2Zmc2V0PSIwLjY4NDEiIHN0eWxlPSJzdG9wLWNvbG9yOiNGQkIwM0IiLz4KPC9saW5lYXJHcmFkaWVudD4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTI3MS42LDBjLTIwLDAtNDEuOSwxMC45LTY1LDMyLjRjLTEwLjksMTAuMS0yMC41LDIxLjEtMjcuNSwyOS44YzAsMCwxMS4yLDEyLjksMjMuNSwyNi44CgljNi43LTguNCwxNi4yLTE5LjgsMjcuMy0zMC4xYzIwLjUtMTkuMiwzMy45LTIzLjEsNDEuNi0yMy4xYzI4LjgsMCw1Mi4yLDI0LjIsNTIuMiw1NC4xYzAsMjkuNi0yMy40LDUzLjgtNTIuMiw1NC4xCgljLTEuNCwwLTMtMC4yLTUtMC42YzguNCwzLjksMTcuNSw2LjcsMjYsNi43YzUyLjgsMCw2My4yLTM2LjUsNjMuOC0zOS4xYzEuNS02LjcsMi40LTEzLjcsMi40LTIwLjlDMzU4LjYsNDAuNCwzMTkuNiwwLDI3MS42LDB6Ii8+CjxsaW5lYXJHcmFkaWVudCBpZD0iU1ZHSURfMl8iIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTMzLjk0NjEiIHkxPSIxMDYuNDI2MiIgeDI9IjEwLjY2NTMiIHkyPSIyMzAuNzIxNSIgZ3JhZGllbnRUcmFuc2Zvcm09Im1hdHJpeCgxIDAgMCAtMSAwIDI3MikiPgoJPHN0b3AgIG9mZnNldD0iMC4yMSIgc3R5bGU9InN0b3AtY29sb3I6I0VEMUU3OSIvPgoJPHN0b3AgIG9mZnNldD0iMC44OTI5IiBzdHlsZT0ic3RvcC1jb2xvcjojNTIyNzg1Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik04Ny4xLDE3OS44YzIwLDAsNDEuOS0xMC45LDY1LTMyLjRjMTAuOS0xMC4xLDIwLjUtMjEuMSwyNy41LTI5LjhjMCwwLTExLjItMTIuOS0yMy41LTI2LjgKCWMtNi43LDguNC0xNi4yLDE5LjgtMjcuMywzMC4xYy0yMC41LDE5LTM0LDIzLjEtNDEuNiwyMy4xYy0yOC44LDAtNTIuMi0yNC4yLTUyLjItNTQuMWMwLTI5LjYsMjMuNC01My44LDUyLjItNTQuMQoJYzEuNCwwLDMsMC4yLDUsMC42Yy04LjQtMy45LTE3LjUtNi43LTI2LTYuN0MxMy40LDI5LjYsMyw2Ni4xLDIuNCw2OC44QzAuOSw3NS41LDAsODIuNSwwLDg5LjdDMCwxMzkuNCwzOSwxNzkuOCw4Ny4xLDE3OS44eiIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNMTI3LjMsNTkuN2MtNS44LTUuNi0zNC0yOC41LTYxLTI5LjNDMTguMSwyOS4yLDQsNjQuMiwyLjcsNjguN0MxMiwyOS41LDQ2LjQsMC4yLDg3LjIsMAoJYzMzLjMsMCw2NywzMi43LDkxLjksNjIuMmMwLDAsMC4xLTAuMSwwLjEtMC4xYzAsMCwxMS4yLDEyLjksMjMuNSwyNi44YzAsMCwxNCwxNi41LDI4LjgsMzFjNS44LDUuNiwzMy45LDI4LjIsNjAuOSwyOQoJYzQ5LjUsMS40LDYzLjItMzUuNiw2My45LTM4LjRjLTkuMSwzOS41LTQzLjYsNjguOS04NC42LDY5LjFjLTMzLjMsMC02Ny0zMi43LTkyLTYyLjJjMCwwLjEtMC4xLDAuMS0wLjEsMC4yCgljMCwwLTExLjItMTIuOS0yMy41LTI2LjhDMTU2LjIsOTAuOCwxNDIuMiw3NC4yLDEyNy4zLDU5Ljd6IE0yLjcsNjkuMWMwLTAuMSwwLTAuMiwwLjEtMC4zQzIuNyw2OC45LDIuNyw2OSwyLjcsNjkuMXoiLz4KPC9zdmc+Cg==",
};
const Stoic = {
id: "Stoic",
providerUrl: "",
transportType: TransportType.STOIC,
label: "Stoic",
icon: "data:image/png;base64,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