export function normalizeArg(val) {
if (val instanceof BigUint64Array) return Array.from(val);
if (val instanceof BigInt64Array) return Array.from(val);
if (val instanceof Uint8Array || Buffer.isBuffer(val)) return Array.from(val);
return val;
}
function wrapClass(Cls) {
if (!Cls) return Cls;
const Wrapper = function (...args) {
return new Cls(...args.map(normalizeArg));
};
Wrapper.prototype = Cls.prototype;
for (const key of Object.getOwnPropertyNames(Cls)) {
if (key === "prototype" || key === "length" || key === "name") continue;
const desc = Object.getOwnPropertyDescriptor(Cls, key);
if (desc && typeof desc.value === "function") {
Wrapper[key] = (...args) => desc.value.apply(Cls, args.map(normalizeArg));
} else if (desc) {
try {
Object.defineProperty(Wrapper, key, desc);
} catch {
}
}
}
return Wrapper;
}
export function wrapClient(rawClient, storeName) {
return new Proxy(rawClient, {
get(target, prop) {
if (prop === "syncState") {
return (...args) => target.syncStateImpl(...args);
}
if (prop === "syncChain") {
return () => target.syncChainImpl();
}
if (prop === "syncNoteTransport") {
return () => target.syncNoteTransportImpl();
}
if (prop === "storeName") {
return storeName || "default";
}
if (prop === "wasmWebClient") {
return target;
}
if (prop === "storeIdentifier") {
return () => target.storeIdentifier?.() ?? storeName ?? "unknown";
}
if (prop === "terminate") {
return () => {};
}
if (prop === "onStateChanged") {
return () => undefined;
}
if (prop === "waitForIdle") {
return () => Promise.resolve();
}
if (prop === "lastAuthError") {
return () => null;
}
if (prop === "newWallet") {
return (mode, authScheme, seed) => {
const normSeed =
seed instanceof Uint8Array || Buffer.isBuffer(seed)
? Array.from(seed)
: seed;
return target
.newWallet(mode, authScheme, normSeed ?? null)
.then((v) => (v === null ? undefined : v));
};
}
const val = target[prop];
if (typeof val === "function") {
const bound = val.bind(target);
return (...args) => {
const result = bound(...args.map(normalizeArg));
if (result && typeof result.then === "function") {
return result.then((v) => (v === null ? undefined : v));
}
return result === null ? undefined : result;
};
}
return val;
},
});
}
function patchSdkPrototypes(rawSdk) {
for (const [cls, aliases] of [
[rawSdk.Account, { to_commitment: "toCommitment" }],
[rawSdk.AccountHeader, { to_commitment: "toCommitment" }],
]) {
if (!cls?.prototype) continue;
for (const [snake, camel] of Object.entries(aliases)) {
if (typeof cls.prototype[camel] === "function" && !cls.prototype[snake]) {
cls.prototype[snake] = cls.prototype[camel];
}
}
}
for (const [cls, methods] of [
[rawSdk.AccountStorage, ["getItem", "getMapEntries", "getMapItem"]],
[rawSdk.NoteConsumability, ["consumableAfterBlock"]],
]) {
if (!cls?.prototype) continue;
for (const method of methods) {
const original = cls.prototype[method];
if (typeof original === "function") {
cls.prototype[method] = function (...args) {
const result = original.apply(this, args);
return result === null ? undefined : result;
};
}
}
}
if (rawSdk.NoteScript) {
if (!rawSdk.NoteScript.p2id && rawSdk.NoteScript.p2Id)
rawSdk.NoteScript.p2id = rawSdk.NoteScript.p2Id;
if (!rawSdk.NoteScript.p2ide && rawSdk.NoteScript.p2Ide)
rawSdk.NoteScript.p2ide = rawSdk.NoteScript.p2Ide;
}
}
function makeArrayPolyfills() {
function polyfill(items) {
const arr =
items === undefined || items === null
? []
: Array.isArray(items)
? [...items]
: [items];
arr.get = (i) => arr[i];
arr.replaceAt = (i, val) => {
arr[i] = val;
return arr;
};
return arr;
}
const names = [
"AccountArray",
"AccountIdArray",
"FeltArray",
"ForeignAccountArray",
"NoteAndArgsArray",
"NoteArray",
"NoteDetailsAndTagArray",
"NoteIdAndArgsArray",
"NoteRecipientArray",
"OutputNoteArray",
"OutputNotesArray",
"StorageSlotArray",
"TransactionScriptInputPairArray",
];
const result = {};
for (const name of names) {
result[name] = polyfill;
}
return result;
}
export function createSdkWrapper(rawSdk) {
patchSdkPrototypes(rawSdk);
return {
...rawSdk,
AccountBuilder: wrapClass(rawSdk.AccountBuilder),
AccountComponent: wrapClass(rawSdk.AccountComponent),
AuthSecretKey: wrapClass(rawSdk.AuthSecretKey),
Felt: wrapClass(rawSdk.Felt),
FungibleAsset: wrapClass(rawSdk.FungibleAsset),
Word: wrapClass(rawSdk.Word),
NoteTag: wrapClass(rawSdk.NoteTag),
...makeArrayPolyfills(),
};
}