@0xsequence/sessions
Advanced tools
Comparing version 1.1.1 to 1.1.2
@@ -702,4 +702,4 @@ 'use strict'; | ||
const fromVersion = signed.fromVersion; | ||
if (fromVersion !== 1) throw new Error("Migration not supported"); | ||
if (!core.v2.config.isWalletConfig(signed.toConfig)) throw new Error("Invalid to config"); | ||
if (fromVersion !== 1) throw new Error('Migration not supported'); | ||
if (!core.v2.config.isWalletConfig(signed.toConfig)) throw new Error('Invalid to config'); | ||
@@ -711,4 +711,4 @@ // Validate migration transaction | ||
} = migration.migration.v1v2.decodeTransaction(signed.tx, contexts); | ||
if (decodedAddress !== address) throw new Error("Invalid migration transaction - address"); | ||
if (core.v2.config.ConfigCoder.imageHashOf(signed.toConfig) != newImageHash) throw new Error("Invalid migration transaction - config"); | ||
if (decodedAddress !== address) throw new Error('Invalid migration transaction - address'); | ||
if (core.v2.config.ConfigCoder.imageHashOf(signed.toConfig) != newImageHash) throw new Error('Invalid migration transaction - config'); | ||
@@ -715,0 +715,0 @@ // Split signature and save each part |
@@ -702,4 +702,4 @@ 'use strict'; | ||
const fromVersion = signed.fromVersion; | ||
if (fromVersion !== 1) throw new Error("Migration not supported"); | ||
if (!core.v2.config.isWalletConfig(signed.toConfig)) throw new Error("Invalid to config"); | ||
if (fromVersion !== 1) throw new Error('Migration not supported'); | ||
if (!core.v2.config.isWalletConfig(signed.toConfig)) throw new Error('Invalid to config'); | ||
@@ -711,4 +711,4 @@ // Validate migration transaction | ||
} = migration.migration.v1v2.decodeTransaction(signed.tx, contexts); | ||
if (decodedAddress !== address) throw new Error("Invalid migration transaction - address"); | ||
if (core.v2.config.ConfigCoder.imageHashOf(signed.toConfig) != newImageHash) throw new Error("Invalid migration transaction - config"); | ||
if (decodedAddress !== address) throw new Error('Invalid migration transaction - address'); | ||
if (core.v2.config.ConfigCoder.imageHashOf(signed.toConfig) != newImageHash) throw new Error('Invalid migration transaction - config'); | ||
@@ -715,0 +715,0 @@ // Split signature and save each part |
@@ -698,4 +698,4 @@ import { v2, v1, universal, commons } from '@0xsequence/core'; | ||
const fromVersion = signed.fromVersion; | ||
if (fromVersion !== 1) throw new Error("Migration not supported"); | ||
if (!v2.config.isWalletConfig(signed.toConfig)) throw new Error("Invalid to config"); | ||
if (fromVersion !== 1) throw new Error('Migration not supported'); | ||
if (!v2.config.isWalletConfig(signed.toConfig)) throw new Error('Invalid to config'); | ||
@@ -707,4 +707,4 @@ // Validate migration transaction | ||
} = migration.v1v2.decodeTransaction(signed.tx, contexts); | ||
if (decodedAddress !== address) throw new Error("Invalid migration transaction - address"); | ||
if (v2.config.ConfigCoder.imageHashOf(signed.toConfig) != newImageHash) throw new Error("Invalid migration transaction - config"); | ||
if (decodedAddress !== address) throw new Error('Invalid migration transaction - address'); | ||
if (v2.config.ConfigCoder.imageHashOf(signed.toConfig) != newImageHash) throw new Error('Invalid migration transaction - config'); | ||
@@ -711,0 +711,0 @@ // Split signature and save each part |
@@ -1,4 +0,4 @@ | ||
import { commons } from "@0xsequence/core"; | ||
import { migrator } from "@0xsequence/migration"; | ||
import { BigNumber, BigNumberish } from "ethers"; | ||
import { commons } from '@0xsequence/core'; | ||
import { migrator } from '@0xsequence/migration'; | ||
import { BigNumber, BigNumberish } from 'ethers'; | ||
import { ConfigTracker, PresignedConfig, PresignedConfigLink } from "../tracker.js"; | ||
@@ -5,0 +5,0 @@ export declare function isDedupedTracker(tracker: any): tracker is DedupedTracker; |
@@ -1,3 +0,3 @@ | ||
import { commons, v1, v2 } from "@0xsequence/core"; | ||
import { ethers } from "ethers"; | ||
import { commons, v1, v2 } from '@0xsequence/core'; | ||
import { ethers } from 'ethers'; | ||
export type PlainNode = { | ||
@@ -4,0 +4,0 @@ left: string; |
import { commons, v1, v2 } from "@0xsequence/core"; | ||
import { ethers } from "ethers"; | ||
import { commons, v1, v2 } from '@0xsequence/core'; | ||
import { ethers } from 'ethers'; | ||
import { PlainNested, PlainNode, PlainV2Config, TrackerStore } from "./index.js"; | ||
import { DBSchema, IDBPDatabase } from 'idb'; | ||
export interface LocalTrackerDBSchema extends DBSchema { | ||
'configs': { | ||
configs: { | ||
key: string; | ||
value: v1.config.WalletConfig | v2.config.WalletConfig | PlainV2Config; | ||
}; | ||
'v2Nodes': { | ||
v2Nodes: { | ||
key: string; | ||
value: v2.config.Topology | PlainNode | PlainNested; | ||
}; | ||
'counterfactualWallets': { | ||
counterfactualWallets: { | ||
key: string; | ||
@@ -22,7 +22,7 @@ value: { | ||
}; | ||
'payloads': { | ||
payloads: { | ||
key: string; | ||
value: commons.signature.SignedPayload; | ||
}; | ||
'signatures': { | ||
signatures: { | ||
key: string; | ||
@@ -34,6 +34,6 @@ value: { | ||
indexes: { | ||
'signer': string; | ||
signer: string; | ||
}; | ||
}; | ||
'migrations': { | ||
migrations: { | ||
key: string; | ||
@@ -48,3 +48,3 @@ value: { | ||
indexes: { | ||
'jump': string; | ||
jump: string; | ||
}; | ||
@@ -51,0 +51,0 @@ }; |
import { commons, v1, v2 } from "@0xsequence/core"; | ||
import { ethers } from "ethers"; | ||
import { commons, v1, v2 } from '@0xsequence/core'; | ||
import { ethers } from 'ethers'; | ||
import { PlainNested, PlainNode, PlainV2Config, TrackerStore } from "./index.js"; | ||
@@ -5,0 +5,0 @@ export declare class MemoryTrackerStore implements TrackerStore { |
{ | ||
"name": "@0xsequence/sessions", | ||
"version": "1.1.1", | ||
"version": "1.1.2", | ||
"description": "tools for migrating sequence wallets to new versions", | ||
@@ -14,5 +14,5 @@ "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/sessions", | ||
"idb": "^7.1.1", | ||
"@0xsequence/core": "1.1.1", | ||
"@0xsequence/migration": "1.1.1", | ||
"@0xsequence/replacer": "1.1.1" | ||
"@0xsequence/core": "1.1.2", | ||
"@0xsequence/migration": "1.1.2", | ||
"@0xsequence/replacer": "1.1.2" | ||
}, | ||
@@ -23,4 +23,4 @@ "devDependencies": { | ||
"nyc": "^15.1.0", | ||
"@0xsequence/signhub": "1.1.1", | ||
"@0xsequence/tests": "1.1.1" | ||
"@0xsequence/signhub": "1.1.2", | ||
"@0xsequence/tests": "1.1.2" | ||
}, | ||
@@ -27,0 +27,0 @@ "files": [ |
@@ -1,3 +0,2 @@ | ||
export * as tracker from './tracker' | ||
export * as trackers from './trackers' |
@@ -13,7 +13,7 @@ import { commons } from '@0xsequence/core' | ||
export type ConfigDataDump = { | ||
configurations: commons.config.Config[], | ||
configurations: commons.config.Config[] | ||
wallets: { | ||
imageHash: string, | ||
imageHash: string | ||
context: commons.context.WalletContext | ||
}[], | ||
}[] | ||
presignedTransactions: PresignedConfigLink[] | ||
@@ -24,4 +24,4 @@ } | ||
loadPresignedConfiguration: (args: { | ||
wallet: string, | ||
fromImageHash: string, | ||
wallet: string | ||
fromImageHash: string | ||
longestPath?: boolean | ||
@@ -34,35 +34,26 @@ }) => Promise<PresignedConfigLink[]> | ||
configOfImageHash: (args: { | ||
imageHash: string, | ||
noCache?: boolean | ||
}) => Promise<commons.config.Config | undefined> | ||
configOfImageHash: (args: { imageHash: string; noCache?: boolean }) => Promise<commons.config.Config | undefined> | ||
saveWalletConfig: (args: { | ||
config: commons.config.Config | ||
}) => Promise<void> | ||
saveWalletConfig: (args: { config: commons.config.Config }) => Promise<void> | ||
imageHashOfCounterfactualWallet: (args: { | ||
wallet: string, | ||
noCache?: boolean | ||
}) => Promise<{ | ||
imageHash: string, | ||
context: commons.context.WalletContext | ||
} | undefined> | ||
imageHashOfCounterfactualWallet: (args: { wallet: string; noCache?: boolean }) => Promise< | ||
| { | ||
imageHash: string | ||
context: commons.context.WalletContext | ||
} | ||
| undefined | ||
> | ||
saveCounterfactualWallet: (args: { | ||
config: commons.config.Config; | ||
context: commons.context.WalletContext[] | ||
}) => Promise<void> | ||
saveCounterfactualWallet: (args: { config: commons.config.Config; context: commons.context.WalletContext[] }) => Promise<void> | ||
walletsOfSigner: (args: { | ||
signer: string, | ||
noCache?: boolean | ||
}) => Promise<{ | ||
wallet: string, | ||
proof: { | ||
digest: string, | ||
chainId: ethers.BigNumber, | ||
signature: string | ||
} | ||
}[]> | ||
walletsOfSigner: (args: { signer: string; noCache?: boolean }) => Promise< | ||
{ | ||
wallet: string | ||
proof: { | ||
digest: string | ||
chainId: ethers.BigNumber | ||
signature: string | ||
} | ||
}[] | ||
> | ||
} |
@@ -1,2 +0,1 @@ | ||
import { commons, universal } from '@0xsequence/core' | ||
@@ -14,3 +13,7 @@ import { migrator } from '@0xsequence/migration' | ||
async loadPresignedConfiguration(args: { wallet: string; fromImageHash: string; longestPath?: boolean | undefined }): Promise<PresignedConfigLink[]> { | ||
async loadPresignedConfiguration(args: { | ||
wallet: string | ||
fromImageHash: string | ||
longestPath?: boolean | undefined | ||
}): Promise<PresignedConfigLink[]> { | ||
// We need to check both, and return the one with the highest checkpoint | ||
@@ -30,28 +33,34 @@ // eventually we could try to combine them, but for now we'll just return | ||
) { | ||
best = ( | ||
args.longestPath === true ? | ||
result1.length > result2.length ? result1 : result2 : | ||
result1.length < result2.length ? result1 : result2 | ||
) | ||
best = | ||
args.longestPath === true | ||
? result1.length > result2.length | ||
? result1 | ||
: result2 | ||
: result1.length < result2.length | ||
? result1 | ||
: result2 | ||
} else { | ||
// Otherwise we need to check the checkpoints | ||
// this requires us to fetch the config for each image hash | ||
const checkpoints = await Promise.all(results.map(async result => { | ||
const r = await result | ||
const last = r[r.length - 1] | ||
if (!last) return undefined | ||
const checkpoints = await Promise.all( | ||
results.map(async result => { | ||
const r = await result | ||
const last = r[r.length - 1] | ||
if (!last) return undefined | ||
// TODO: This will fire a lot of requests, optimize it | ||
const config = await this.configOfImageHash({ imageHash: last.nextImageHash }) | ||
if (!config) return undefined | ||
// TODO: This will fire a lot of requests, optimize it | ||
const config = await this.configOfImageHash({ imageHash: last.nextImageHash }) | ||
if (!config) return undefined | ||
return { checkpoint: universal.genericCoderFor(config.version).config.checkpointOf(config), result: r } | ||
})) | ||
return { checkpoint: universal.genericCoderFor(config.version).config.checkpointOf(config), result: r } | ||
}) | ||
) | ||
best = checkpoints.reduce((acc, val) => { | ||
if (!val) return acc | ||
if (!acc) return val | ||
if (val.checkpoint.gt(acc.checkpoint)) return val | ||
return acc | ||
})?.result ?? [] | ||
best = | ||
checkpoints.reduce((acc, val) => { | ||
if (!val) return acc | ||
if (!acc) return val | ||
if (val.checkpoint.gt(acc.checkpoint)) return val | ||
return acc | ||
})?.result ?? [] | ||
} | ||
@@ -68,3 +77,3 @@ | ||
async configOfImageHash(args: { imageHash: string, noCache?: boolean }): Promise<commons.config.Config | undefined> { | ||
async configOfImageHash(args: { imageHash: string; noCache?: boolean }): Promise<commons.config.Config | undefined> { | ||
// We first check the cache, if it's not there, we check the tracker | ||
@@ -89,3 +98,6 @@ // and then we save it to the cache | ||
async imageHashOfCounterfactualWallet(args: { wallet: string, noCache?: boolean }): Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> { | ||
async imageHashOfCounterfactualWallet(args: { | ||
wallet: string | ||
noCache?: boolean | ||
}): Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> { | ||
// We first check the cache, if it's not there, we check the tracker | ||
@@ -106,11 +118,17 @@ // and then we save it to the cache | ||
} | ||
return result2 | ||
} | ||
async saveCounterfactualWallet(args: { config: commons.config.Config; context: commons.context.WalletContext[] }): Promise<void> { | ||
async saveCounterfactualWallet(args: { | ||
config: commons.config.Config | ||
context: commons.context.WalletContext[] | ||
}): Promise<void> { | ||
await Promise.all([this.tracker.saveCounterfactualWallet(args), this.cache.saveCounterfactualWallet(args)]) | ||
} | ||
async walletsOfSigner(args: { signer: string, noCache?: boolean }): Promise<{ wallet: string; proof: { digest: string; chainId: ethers.BigNumber; signature: string } }[]> { | ||
async walletsOfSigner(args: { | ||
signer: string | ||
noCache?: boolean | ||
}): Promise<{ wallet: string; proof: { digest: string; chainId: ethers.BigNumber; signature: string } }[]> { | ||
if (args.noCache) { | ||
@@ -123,3 +141,3 @@ return this.tracker.walletsOfSigner(args) | ||
const results = await Promise.all([this.tracker.walletsOfSigner(args), this.cache.walletsOfSigner(args)]) | ||
const wallets = new Map<string, { wallet: string; proof: { digest: string; chainId: ethers.BigNumber; signature: string} } >() | ||
const wallets = new Map<string, { wallet: string; proof: { digest: string; chainId: ethers.BigNumber; signature: string } }>() | ||
@@ -135,7 +153,17 @@ for (const result of results) { | ||
async saveWitnesses(args: { wallet: string; digest: string; chainId: ethers.BigNumberish; signatures: string[] }): Promise<void> { | ||
async saveWitnesses(args: { | ||
wallet: string | ||
digest: string | ||
chainId: ethers.BigNumberish | ||
signatures: string[] | ||
}): Promise<void> { | ||
await Promise.all([this.tracker.saveWitnesses(args), this.cache.saveWitnesses(args)]) | ||
} | ||
async getMigration(address: string, fromImageHash: string, fromVersion: number, chainId: ethers.BigNumberish): Promise<migrator.SignedMigration | undefined> { | ||
async getMigration( | ||
address: string, | ||
fromImageHash: string, | ||
fromVersion: number, | ||
chainId: ethers.BigNumberish | ||
): Promise<migrator.SignedMigration | undefined> { | ||
// We first check the cache, if it's not there, we check the tracker | ||
@@ -155,5 +183,12 @@ // NOTICE: we could eventually try to combine the two, but now we just have 1 migration | ||
async saveMigration(address: string, signed: migrator.SignedMigration, contexts: commons.context.VersionedContext): Promise<void> { | ||
await Promise.all([this.tracker.saveMigration(address, signed, contexts), this.cache.saveMigration(address, signed, contexts)]) | ||
async saveMigration( | ||
address: string, | ||
signed: migrator.SignedMigration, | ||
contexts: commons.context.VersionedContext | ||
): Promise<void> { | ||
await Promise.all([ | ||
this.tracker.saveMigration(address, signed, contexts), | ||
this.cache.saveMigration(address, signed, contexts) | ||
]) | ||
} | ||
} |
@@ -1,6 +0,6 @@ | ||
import { commons } from "@0xsequence/core" | ||
import { migrator } from "@0xsequence/migration"; | ||
import { BigNumber, BigNumberish } from "ethers"; | ||
import { ConfigTracker, PresignedConfig, PresignedConfigLink } from "../tracker"; | ||
import { PromiseCache } from "./promise-cache"; | ||
import { commons } from '@0xsequence/core' | ||
import { migrator } from '@0xsequence/migration' | ||
import { BigNumber, BigNumberish } from 'ethers' | ||
import { ConfigTracker, PresignedConfig, PresignedConfigLink } from '../tracker' | ||
import { PromiseCache } from './promise-cache' | ||
@@ -15,3 +15,3 @@ export function isDedupedTracker(tracker: any): tracker is DedupedTracker { | ||
export class DedupedTracker implements migrator.PresignedMigrationTracker, ConfigTracker { | ||
private cache: PromiseCache = new PromiseCache(); | ||
private cache: PromiseCache = new PromiseCache() | ||
@@ -28,8 +28,21 @@ constructor( | ||
configOfImageHash(args: { imageHash: string; }): Promise<commons.config.Config | undefined> { | ||
configOfImageHash(args: { imageHash: string }): Promise<commons.config.Config | undefined> { | ||
return this.cache.do('configOfImageHash', this.window, args => this.tracker.configOfImageHash(args), args) | ||
} | ||
getMigration(address: string, fromImageHash: string, fromVersion: number, chainId: BigNumberish): Promise<migrator.SignedMigration | undefined> { | ||
return this.cache.do('getMigration', this.window, (...args) => this.tracker.getMigration(...args), address, fromImageHash, fromVersion, chainId) | ||
getMigration( | ||
address: string, | ||
fromImageHash: string, | ||
fromVersion: number, | ||
chainId: BigNumberish | ||
): Promise<migrator.SignedMigration | undefined> { | ||
return this.cache.do( | ||
'getMigration', | ||
this.window, | ||
(...args) => this.tracker.getMigration(...args), | ||
address, | ||
fromImageHash, | ||
fromVersion, | ||
chainId | ||
) | ||
} | ||
@@ -41,3 +54,7 @@ | ||
loadPresignedConfiguration(args: { wallet: string; fromImageHash: string; longestPath?: boolean | undefined; }): Promise<PresignedConfigLink[]> { | ||
loadPresignedConfiguration(args: { | ||
wallet: string | ||
fromImageHash: string | ||
longestPath?: boolean | undefined | ||
}): Promise<PresignedConfigLink[]> { | ||
return this.cache.do('loadPresignedConfiguration', this.window, args => this.tracker.loadPresignedConfiguration(args), args) | ||
@@ -50,21 +67,30 @@ } | ||
saveWitnesses(args: { wallet: string; digest: string; chainId: BigNumberish; signatures: string[]; }): Promise<void> { | ||
saveWitnesses(args: { wallet: string; digest: string; chainId: BigNumberish; signatures: string[] }): Promise<void> { | ||
return this.cache.do('saveWitnesses', undefined, args => this.tracker.saveWitnesses(args), args) | ||
} | ||
saveWalletConfig(args: { config: commons.config.Config; }): Promise<void> { | ||
saveWalletConfig(args: { config: commons.config.Config }): Promise<void> { | ||
return this.cache.do('saveWalletConfig', undefined, args => this.tracker.saveWalletConfig(args), args) | ||
} | ||
imageHashOfCounterfactualWallet(args: { wallet: string; }): Promise<{ imageHash: string; context: commons.context.WalletContext; } | undefined> { | ||
return this.cache.do('imageHashOfCounterfactualWallet', undefined, args => this.tracker.imageHashOfCounterfactualWallet(args), args) | ||
imageHashOfCounterfactualWallet(args: { | ||
wallet: string | ||
}): Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> { | ||
return this.cache.do( | ||
'imageHashOfCounterfactualWallet', | ||
undefined, | ||
args => this.tracker.imageHashOfCounterfactualWallet(args), | ||
args | ||
) | ||
} | ||
saveCounterfactualWallet(args: { config: commons.config.Config; context: commons.context.WalletContext[]; }): Promise<void> { | ||
saveCounterfactualWallet(args: { config: commons.config.Config; context: commons.context.WalletContext[] }): Promise<void> { | ||
return this.cache.do('saveCounterfactualWallet', undefined, args => this.tracker.saveCounterfactualWallet(args), args) | ||
} | ||
walletsOfSigner(args: { signer: string; }): Promise<{ wallet: string; proof: { digest: string; chainId: BigNumber; signature: string; }; }[]> { | ||
walletsOfSigner(args: { | ||
signer: string | ||
}): Promise<{ wallet: string; proof: { digest: string; chainId: BigNumber; signature: string } }[]> { | ||
return this.cache.do('walletsOfSigner', this.window, args => this.tracker.walletsOfSigner(args), args) | ||
} | ||
} |
@@ -92,5 +92,3 @@ import { commons, universal, v1, v2 } from '@0xsequence/core' | ||
saveWalletConfig = async (args: { | ||
config: commons.config.Config | ||
}): Promise<void> => { | ||
saveWalletConfig = async (args: { config: commons.config.Config }): Promise<void> => { | ||
const { config } = args | ||
@@ -134,5 +132,3 @@ if (v1.config.ConfigCoder.isWalletConfig(config)) { | ||
configOfImageHash = async (args: { | ||
imageHash: string | ||
}): Promise<commons.config.Config | undefined> => { | ||
configOfImageHash = async (args: { imageHash: string }): Promise<commons.config.Config | undefined> => { | ||
const { imageHash } = args | ||
@@ -185,6 +181,9 @@ | ||
wallet: string | ||
}): Promise<{ | ||
imageHash: string, | ||
context: commons.context.WalletContext | ||
} | undefined> => { | ||
}): Promise< | ||
| { | ||
imageHash: string | ||
context: commons.context.WalletContext | ||
} | ||
| undefined | ||
> => { | ||
const { wallet } = args | ||
@@ -201,5 +200,3 @@ const result = await this.store.loadCounterfactualWallet(wallet) | ||
savePayload = async (args: { | ||
payload: commons.signature.SignedPayload | ||
}): Promise<void> => { | ||
savePayload = async (args: { payload: commons.signature.SignedPayload }): Promise<void> => { | ||
const { payload } = args | ||
@@ -213,5 +210,3 @@ | ||
payloadOfSubdigest = async (args: { | ||
subdigest: string | ||
}): Promise<commons.signature.SignedPayload | undefined> => { | ||
payloadOfSubdigest = async (args: { subdigest: string }): Promise<commons.signature.SignedPayload | undefined> => { | ||
if (this.payloadOfSubdigestCache[args.subdigest]) { | ||
@@ -261,4 +256,4 @@ return this.payloadOfSubdigestCache[args.subdigest] | ||
loadPresignedConfiguration = async (args: { | ||
wallet: string, | ||
fromImageHash: string, | ||
wallet: string | ||
fromImageHash: string | ||
longestPath?: boolean | ||
@@ -274,35 +269,43 @@ }): Promise<PresignedConfigLink[]> => { | ||
// Get all subdigests for the config members | ||
const signers = v2.config.signersOf(fromConfig.tree).map((s) => s.address) | ||
const subdigestsOfSigner = await Promise.all(signers.map((s) => this.store.loadSubdigestsOfSigner(s))) | ||
const signers = v2.config.signersOf(fromConfig.tree).map(s => s.address) | ||
const subdigestsOfSigner = await Promise.all(signers.map(s => this.store.loadSubdigestsOfSigner(s))) | ||
const subdigests = [...new Set(subdigestsOfSigner.flat())] | ||
// Get all unique payloads | ||
const payloads = await Promise.all([...new Set(subdigests)] | ||
.map(async (s) => ({ ...(await this.payloadOfSubdigest({ subdigest: s })), subdigest: s }))) | ||
const payloads = await Promise.all( | ||
[...new Set(subdigests)].map(async s => ({ ...(await this.payloadOfSubdigest({ subdigest: s })), subdigest: s })) | ||
) | ||
// Get all possible next imageHashes based on the payloads | ||
const nextImageHashes = payloads | ||
.filter((p) => p?.message && p?.address && p.address === wallet) | ||
.map((p) => ({ payload: p, nextImageHash: v2.chained.decodeMessageSetImageHash(p!.message!) })) | ||
.filter((p) => p?.nextImageHash) as { payload: commons.signature.SignedPayload & { subdigest: string }, nextImageHash: string }[] | ||
.filter(p => p?.message && p?.address && p.address === wallet) | ||
.map(p => ({ payload: p, nextImageHash: v2.chained.decodeMessageSetImageHash(p!.message!) })) | ||
.filter(p => p?.nextImageHash) as { | ||
payload: commons.signature.SignedPayload & { subdigest: string } | ||
nextImageHash: string | ||
}[] | ||
// Build a signature for each next imageHash | ||
// and filter out the ones that don't have enough weight | ||
let bestCandidate: { | ||
nextImageHash: string, | ||
checkpoint: ethers.BigNumber, | ||
signature: string, | ||
} | undefined | ||
let bestCandidate: | ||
| { | ||
nextImageHash: string | ||
checkpoint: ethers.BigNumber | ||
signature: string | ||
} | ||
| undefined | ||
const nextConfigsAndCheckpoints = await Promise.all(nextImageHashes.map(async ({ nextImageHash, payload }) => { | ||
const nextConfig = await this.configOfImageHash({ imageHash: nextImageHash }) | ||
if (!nextConfig || !v2.config.isWalletConfig(nextConfig)) return undefined | ||
const nextCheckpoint = ethers.BigNumber.from(nextConfig.checkpoint) | ||
return { nextConfig, nextCheckpoint, nextImageHash, payload } | ||
})) | ||
const nextConfigsAndCheckpoints = await Promise.all( | ||
nextImageHashes.map(async ({ nextImageHash, payload }) => { | ||
const nextConfig = await this.configOfImageHash({ imageHash: nextImageHash }) | ||
if (!nextConfig || !v2.config.isWalletConfig(nextConfig)) return undefined | ||
const nextCheckpoint = ethers.BigNumber.from(nextConfig.checkpoint) | ||
return { nextConfig, nextCheckpoint, nextImageHash, payload } | ||
}) | ||
) | ||
const sortedNextConfigsAndCheckpoints = nextConfigsAndCheckpoints | ||
.filter((c) => c !== undefined) | ||
.filter((c) => c!.nextCheckpoint.gt(fromConfig.checkpoint)) | ||
.sort((a, b) => ( | ||
.filter(c => c !== undefined) | ||
.filter(c => c!.nextCheckpoint.gt(fromConfig.checkpoint)) | ||
.sort((a, b) => | ||
// If we are looking for the longest path, sort by ascending checkpoint | ||
@@ -316,8 +319,4 @@ // because we want to find the smalles jump, and we should start with the | ||
// But we can try to optimize for the most common case. | ||
a!.nextCheckpoint.gt(b!.nextCheckpoint) ? ( | ||
longestPath ? 1 : -1 | ||
) : ( | ||
longestPath ? -1 : 1 | ||
) | ||
)) | ||
a!.nextCheckpoint.gt(b!.nextCheckpoint) ? (longestPath ? 1 : -1) : longestPath ? -1 : 1 | ||
) | ||
@@ -374,3 +373,3 @@ for (const entry of sortedNextConfigsAndCheckpoints) { | ||
} | ||
if (!bestCandidate) { | ||
@@ -387,7 +386,10 @@ return [] | ||
return [{ | ||
wallet, | ||
nextImageHash: bestCandidate.nextImageHash, | ||
signature: bestCandidate.signature | ||
}, ...nextStep] | ||
return [ | ||
{ | ||
wallet, | ||
nextImageHash: bestCandidate.nextImageHash, | ||
signature: bestCandidate.signature | ||
}, | ||
...nextStep | ||
] | ||
} | ||
@@ -404,3 +406,3 @@ | ||
address: args.wallet, | ||
chainId: args.chainId, | ||
chainId: args.chainId | ||
} | ||
@@ -427,20 +429,23 @@ | ||
signer: string | ||
}): Promise<{ | ||
wallet: string, | ||
proof: { | ||
digest: string, | ||
chainId: ethers.BigNumber, | ||
signature: string | ||
} | ||
}[]> => { | ||
}): Promise< | ||
{ | ||
wallet: string | ||
proof: { | ||
digest: string | ||
chainId: ethers.BigNumber | ||
signature: string | ||
} | ||
}[] | ||
> => { | ||
const subdigests = await this.store.loadSubdigestsOfSigner(args.signer) | ||
const payloads = await Promise.all(subdigests.map((s) => this.payloadOfSubdigest({ subdigest: s }))) | ||
.then((p) => p.filter((p) => p !== undefined) as commons.signature.SignedPayload[]) | ||
const payloads = await Promise.all(subdigests.map(s => this.payloadOfSubdigest({ subdigest: s }))).then( | ||
p => p.filter(p => p !== undefined) as commons.signature.SignedPayload[] | ||
) | ||
// filter unique wallets, and provide a proof for each wallet | ||
const result: { | ||
wallet: string, | ||
wallet: string | ||
proof: { | ||
digest: string, | ||
chainId: ethers.BigNumber, | ||
digest: string | ||
chainId: ethers.BigNumber | ||
signature: string | ||
@@ -452,3 +457,3 @@ } | ||
const wallet = payload.address | ||
if (result.find((r) => r.wallet === wallet)) continue | ||
if (result.find(r => r.wallet === wallet)) continue | ||
@@ -478,12 +483,10 @@ const subdigest = commons.signature.subdigestOf(payload) | ||
const fromVersion = signed.fromVersion | ||
if (fromVersion !== 1) throw new Error("Migration not supported") | ||
if (!v2.config.isWalletConfig(signed.toConfig)) throw new Error("Invalid to config") | ||
if (fromVersion !== 1) throw new Error('Migration not supported') | ||
if (!v2.config.isWalletConfig(signed.toConfig)) throw new Error('Invalid to config') | ||
// Validate migration transaction | ||
const { newImageHash, address: decodedAddress } = migration.v1v2.decodeTransaction(signed.tx, contexts) | ||
if (decodedAddress !== address) throw new Error("Invalid migration transaction - address") | ||
if ( | ||
v2.config.ConfigCoder.imageHashOf(signed.toConfig) != | ||
newImageHash | ||
) throw new Error("Invalid migration transaction - config") | ||
if (decodedAddress !== address) throw new Error('Invalid migration transaction - address') | ||
if (v2.config.ConfigCoder.imageHashOf(signed.toConfig) != newImageHash) | ||
throw new Error('Invalid migration transaction - config') | ||
@@ -541,56 +544,58 @@ // Split signature and save each part | ||
// and see which one has enough signers to be valid (for the current config) | ||
const candidates = await Promise.all(txs.map(async (tx) => { | ||
const { subdigest, toImageHash } = tx | ||
const payload = await this.payloadOfSubdigest({ subdigest }) | ||
if (!payload || !payload.message) return undefined | ||
if (!ethers.BigNumber.from(chainId).eq(payload.chainId)) return undefined | ||
const candidates = await Promise.all( | ||
txs.map(async tx => { | ||
const { subdigest, toImageHash } = tx | ||
const payload = await this.payloadOfSubdigest({ subdigest }) | ||
if (!payload || !payload.message) return undefined | ||
if (!ethers.BigNumber.from(chainId).eq(payload.chainId)) return undefined | ||
const signers = coder.config.signersOf(currentConfig as any).map((s) => s.address) | ||
const signers = coder.config.signersOf(currentConfig as any).map(s => s.address) | ||
// Get all signatures (for all signers) for this subdigest | ||
const signatures = new Map( | ||
( | ||
await Promise.all( | ||
signers.map(async signer => { | ||
const signature = await this.store.loadSignatureOfSubdigest(signer, subdigest) | ||
if (!signature) { | ||
return [signer, undefined] | ||
} | ||
// Get all signatures (for all signers) for this subdigest | ||
const signatures = new Map( | ||
( | ||
await Promise.all( | ||
signers.map(async signer => { | ||
const signature = await this.store.loadSignatureOfSubdigest(signer, subdigest) | ||
if (!signature) { | ||
return [signer, undefined] | ||
} | ||
const replacedSignature = ethers.utils.hexlify( | ||
this.useEIP5719 ? await this.cachedEIP5719.runByEIP5719(signer, subdigest, signature) : signature | ||
) | ||
const replacedSignature = ethers.utils.hexlify( | ||
this.useEIP5719 ? await this.cachedEIP5719.runByEIP5719(signer, subdigest, signature) : signature | ||
) | ||
const isDynamic = commons.signer.tryRecoverSigner(subdigest, replacedSignature) !== signer | ||
const isDynamic = commons.signer.tryRecoverSigner(subdigest, replacedSignature) !== signer | ||
return [signer, { isDynamic, signature: replacedSignature }] | ||
}) | ||
) | ||
).filter((signature): signature is [string, commons.signature.SignaturePart] => Boolean(signature[1])) | ||
) | ||
return [signer, { isDynamic, signature: replacedSignature }] | ||
}) | ||
) | ||
).filter((signature): signature is [string, commons.signature.SignaturePart] => Boolean(signature[1])) | ||
) | ||
// Encode signature parts into a single signature | ||
const encoded = coder.signature.encodeSigners(currentConfig as any, signatures, [], chainId) | ||
if (!encoded || encoded.weight < currentConfig.threshold) return undefined | ||
// Encode signature parts into a single signature | ||
const encoded = coder.signature.encodeSigners(currentConfig as any, signatures, [], chainId) | ||
if (!encoded || encoded.weight < currentConfig.threshold) return undefined | ||
// Unpack payload (it should have transactions) | ||
const [nonce, transactions] = commons.transaction.unpackMetaTransactionsData(payload.message) | ||
// Unpack payload (it should have transactions) | ||
const [nonce, transactions] = commons.transaction.unpackMetaTransactionsData(payload.message) | ||
return { | ||
tx: { | ||
entrypoint: address, | ||
transactions: commons.transaction.fromTxAbiEncode(transactions), | ||
chainId: chainId, | ||
nonce: nonce, | ||
signature: encoded.encoded, | ||
intent: { | ||
id: subdigest, | ||
wallet: address | ||
} | ||
}, | ||
toConfig: await this.configOfImageHash({ imageHash: toImageHash }), | ||
fromVersion, | ||
toVersion: fromVersion + 1 | ||
} as migrator.SignedMigration | ||
})).then(c => c.filter(c => c !== undefined)) | ||
return { | ||
tx: { | ||
entrypoint: address, | ||
transactions: commons.transaction.fromTxAbiEncode(transactions), | ||
chainId: chainId, | ||
nonce: nonce, | ||
signature: encoded.encoded, | ||
intent: { | ||
id: subdigest, | ||
wallet: address | ||
} | ||
}, | ||
toConfig: await this.configOfImageHash({ imageHash: toImageHash }), | ||
fromVersion, | ||
toVersion: fromVersion + 1 | ||
} as migrator.SignedMigration | ||
}) | ||
).then(c => c.filter(c => c !== undefined)) | ||
@@ -597,0 +602,0 @@ // Return the first valid candidate |
@@ -5,24 +5,28 @@ import { ConfigTracker, PresignedConfig, PresignedConfigLink } from '../tracker' | ||
import { commons, universal } from '@0xsequence/core' | ||
import { LocalConfigTracker } from './local'; | ||
import { LocalConfigTracker } from './local' | ||
export function raceUntil<T>(promises: Promise<T>[], fallback: T, evalRes: (val: T) => boolean): Promise<T> { | ||
return new Promise((resolve) => { | ||
return new Promise(resolve => { | ||
let count = 0 | ||
promises.forEach(p => p.then((val: T) => { | ||
if (evalRes(val)) { | ||
resolve(val) | ||
} else { | ||
count++ | ||
if (count === promises.length) { | ||
resolve(fallback) | ||
} | ||
} | ||
}).catch(() => { | ||
// Ignore | ||
count++ | ||
if (count === promises.length) { | ||
resolve(fallback) | ||
} | ||
})) | ||
promises.forEach(p => | ||
p | ||
.then((val: T) => { | ||
if (evalRes(val)) { | ||
resolve(val) | ||
} else { | ||
count++ | ||
if (count === promises.length) { | ||
resolve(fallback) | ||
} | ||
} | ||
}) | ||
.catch(() => { | ||
// Ignore | ||
count++ | ||
if (count === promises.length) { | ||
resolve(fallback) | ||
} | ||
}) | ||
) | ||
}) | ||
@@ -42,3 +46,3 @@ } | ||
// We try to find a complete configuration, we race so that we don't wait for all trackers to respond | ||
const result1 = await raceUntil(requests, undefined, (val) => { | ||
const result1 = await raceUntil(requests, undefined, val => { | ||
if (val?.res === undefined) return false | ||
@@ -70,7 +74,9 @@ return universal.genericCoderFor(val.res.version).config.isComplete(val.res) | ||
async saveWalletConfig(args: { config: commons.config.Config, skipTracker?: number }): Promise<void> { | ||
await Promise.all(this.trackers.map((t, i) => { | ||
if (i === args.skipTracker) return | ||
return t.saveWalletConfig(args) | ||
})) | ||
async saveWalletConfig(args: { config: commons.config.Config; skipTracker?: number }): Promise<void> { | ||
await Promise.all( | ||
this.trackers.map((t, i) => { | ||
if (i === args.skipTracker) return | ||
return t.saveWalletConfig(args) | ||
}) | ||
) | ||
} | ||
@@ -111,6 +117,11 @@ | ||
async walletsOfSigner(args: { signer: string }): Promise<{ wallet: string; proof: { digest: string; chainId: BigNumber; signature: string } }[]> { | ||
async walletsOfSigner(args: { | ||
signer: string | ||
}): Promise<{ wallet: string; proof: { digest: string; chainId: BigNumber; signature: string } }[]> { | ||
// We can't race here, because there is no "correct" response | ||
// we just return the union of all results, skipping duplicates | ||
const results = await allSafe(this.trackers.map(t => t.walletsOfSigner(args)), []).then((r) => r.flat()) | ||
const results = await allSafe( | ||
this.trackers.map(t => t.walletsOfSigner(args)), | ||
[] | ||
).then(r => r.flat()) | ||
@@ -146,16 +157,26 @@ const wallets: { [wallet: string]: { digest: string; chainId: BigNumber; signature: string } } = {} | ||
async loadPresignedConfiguration(args: { wallet: string; fromImageHash: string; longestPath?: boolean | undefined }): Promise<PresignedConfigLink[]> { | ||
async loadPresignedConfiguration(args: { | ||
wallet: string | ||
fromImageHash: string | ||
longestPath?: boolean | undefined | ||
}): Promise<PresignedConfigLink[]> { | ||
// We can't race here, because any of the trackers could have a new "link" in the chain | ||
const results = await allSafe(this.trackers.map((t) => t.loadPresignedConfiguration(args)), []) | ||
const results = await allSafe( | ||
this.trackers.map(t => t.loadPresignedConfiguration(args)), | ||
[] | ||
) | ||
// The "best" result is the one with the highest checkpoint | ||
const checkpoints = await allSafe(results.map(async (r) => { | ||
const last = r[r.length - 1] | ||
const checkpoints = await allSafe( | ||
results.map(async r => { | ||
const last = r[r.length - 1] | ||
// TODO: This will fire a lot of requests, optimize it | ||
const config = await this.configOfImageHash({ imageHash: last.nextImageHash }) | ||
if (!config) return undefined | ||
// TODO: This will fire a lot of requests, optimize it | ||
const config = await this.configOfImageHash({ imageHash: last.nextImageHash }) | ||
if (!config) return undefined | ||
return { checkpoint: universal.genericCoderFor(config.version).config.checkpointOf(config), result: r } | ||
}), undefined) | ||
return { checkpoint: universal.genericCoderFor(config.version).config.checkpointOf(config), result: r } | ||
}), | ||
undefined | ||
) | ||
@@ -196,3 +217,8 @@ const best = checkpoints.reduce((acc, val) => { | ||
async getMigration(address: string, fromImageHash: string, fromVersion: number, chainId: BigNumberish): Promise<migrator.SignedMigration | undefined> { | ||
async getMigration( | ||
address: string, | ||
fromImageHash: string, | ||
fromVersion: number, | ||
chainId: BigNumberish | ||
): Promise<migrator.SignedMigration | undefined> { | ||
// TODO: Backfeed migration results to other trackers | ||
@@ -203,5 +229,9 @@ const results = await Promise.all(this.trackers.map(t => t.getMigration(address, fromImageHash, fromVersion, chainId))) | ||
async saveMigration(address: string, signed: migrator.SignedMigration, contexts: commons.context.VersionedContext): Promise<void> { | ||
async saveMigration( | ||
address: string, | ||
signed: migrator.SignedMigration, | ||
contexts: commons.context.VersionedContext | ||
): Promise<void> { | ||
await Promise.all(this.trackers.map(t => t.saveMigration(address, signed, contexts))) | ||
} | ||
} |
@@ -10,3 +10,6 @@ import { commons, universal, v1, v2 } from '@0xsequence/core' | ||
constructor(hostname: string, public readonly onlyRecoverable: boolean = true) { | ||
constructor( | ||
hostname: string, | ||
public readonly onlyRecoverable: boolean = true | ||
) { | ||
this.sessions = new Sessions(hostname, fetch) | ||
@@ -60,3 +63,3 @@ } | ||
if (this.onlyRecoverable) { | ||
filteredSignatures = filteredSignatures.filter((signature) => { | ||
filteredSignatures = filteredSignatures.filter(signature => { | ||
return commons.signer.canRecover(signature) | ||
@@ -212,3 +215,7 @@ }) | ||
async saveMigration(wallet: string, signed: migrator.SignedMigration, _contexts: commons.context.VersionedContext): Promise<void> { | ||
async saveMigration( | ||
wallet: string, | ||
signed: migrator.SignedMigration, | ||
_contexts: commons.context.VersionedContext | ||
): Promise<void> { | ||
await this.sessions.saveMigration({ | ||
@@ -215,0 +222,0 @@ wallet, |
@@ -9,9 +9,9 @@ /* eslint-disable */ | ||
// WebRPC description and code-gen version | ||
export const WebRPCVersion = "v1" | ||
export const WebRPCVersion = 'v1' | ||
// Schema version of your RIDL schema | ||
export const WebRPCSchemaVersion = "v0.0.1" | ||
export const WebRPCSchemaVersion = 'v0.0.1' | ||
// Schema hash generated from your RIDL schema | ||
export const WebRPCSchemaHash = "b96502864e03f0bea75f41cafaf2178946a9e3b7" | ||
export const WebRPCSchemaHash = 'b96502864e03f0bea75f41cafaf2178946a9e3b7' | ||
@@ -80,7 +80,5 @@ // | ||
export interface PingArgs { | ||
} | ||
export interface PingArgs {} | ||
export interface PingReturn { | ||
} | ||
export interface PingReturn {} | ||
export interface ConfigArgs { | ||
@@ -92,3 +90,3 @@ imageHash: string | ||
version: number | ||
config: any | ||
config: any | ||
} | ||
@@ -100,3 +98,3 @@ export interface WalletsArgs { | ||
export interface WalletsReturn { | ||
wallets: {[key: string]: Signature} | ||
wallets: { [key: string]: Signature } | ||
} | ||
@@ -109,3 +107,3 @@ export interface DeployHashArgs { | ||
deployHash: string | ||
context: Context | ||
context: Context | ||
} | ||
@@ -119,3 +117,3 @@ export interface ConfigUpdatesArgs { | ||
export interface ConfigUpdatesReturn { | ||
updates: Array<ConfigUpdate> | ||
updates: Array<ConfigUpdate> | ||
} | ||
@@ -130,3 +128,3 @@ export interface MigrationsArgs { | ||
export interface MigrationsReturn { | ||
migrations: {[key: string]: {[key: number]: {[key: string]: TransactionBundle}}} | ||
migrations: { [key: string]: { [key: number]: { [key: string]: TransactionBundle } } } | ||
} | ||
@@ -138,4 +136,3 @@ export interface SaveConfigArgs { | ||
export interface SaveConfigReturn { | ||
} | ||
export interface SaveConfigReturn {} | ||
export interface SaveWalletArgs { | ||
@@ -146,4 +143,3 @@ version: number | ||
export interface SaveWalletReturn { | ||
} | ||
export interface SaveWalletReturn {} | ||
export interface SaveSignatureArgs { | ||
@@ -157,4 +153,3 @@ wallet: string | ||
export interface SaveSignatureReturn { | ||
} | ||
export interface SaveSignatureReturn {} | ||
export interface SaveSignerSignaturesArgs { | ||
@@ -168,4 +163,3 @@ wallet: string | ||
export interface SaveSignerSignaturesReturn { | ||
} | ||
export interface SaveSignerSignaturesReturn {} | ||
export interface SaveMigrationArgs { | ||
@@ -183,7 +177,4 @@ wallet: string | ||
export interface SaveMigrationReturn { | ||
} | ||
export interface SaveMigrationReturn {} | ||
// | ||
@@ -205,23 +196,17 @@ // Client | ||
} | ||
ping = (headers?: object): Promise<PingReturn> => { | ||
return this.fetch( | ||
this.url('Ping'), | ||
createHTTPRequest({}, headers) | ||
).then((res) => { | ||
return this.fetch(this.url('Ping'), createHTTPRequest({}, headers)).then(res => { | ||
return buildResponse(res).then(_data => { | ||
return { | ||
} | ||
return {} | ||
}) | ||
}) | ||
} | ||
config = (args: ConfigArgs, headers?: object): Promise<ConfigReturn> => { | ||
return this.fetch( | ||
this.url('Config'), | ||
createHTTPRequest(args, headers)).then((res) => { | ||
return this.fetch(this.url('Config'), createHTTPRequest(args, headers)).then(res => { | ||
return buildResponse(res).then(_data => { | ||
return { | ||
version: <number>(_data.version), | ||
config: <any>(_data.config) | ||
version: <number>_data.version, | ||
config: <any>_data.config | ||
} | ||
@@ -231,10 +216,8 @@ }) | ||
} | ||
wallets = (args: WalletsArgs, headers?: object): Promise<WalletsReturn> => { | ||
return this.fetch( | ||
this.url('Wallets'), | ||
createHTTPRequest(args, headers)).then((res) => { | ||
return this.fetch(this.url('Wallets'), createHTTPRequest(args, headers)).then(res => { | ||
return buildResponse(res).then(_data => { | ||
return { | ||
wallets: <{[key: string]: Signature}>(_data.wallets) | ||
wallets: <{ [key: string]: Signature }>_data.wallets | ||
} | ||
@@ -244,11 +227,9 @@ }) | ||
} | ||
deployHash = (args: DeployHashArgs, headers?: object): Promise<DeployHashReturn> => { | ||
return this.fetch( | ||
this.url('DeployHash'), | ||
createHTTPRequest(args, headers)).then((res) => { | ||
return this.fetch(this.url('DeployHash'), createHTTPRequest(args, headers)).then(res => { | ||
return buildResponse(res).then(_data => { | ||
return { | ||
deployHash: <string>(_data.deployHash), | ||
context: <Context>(_data.context) | ||
deployHash: <string>_data.deployHash, | ||
context: <Context>_data.context | ||
} | ||
@@ -258,10 +239,8 @@ }) | ||
} | ||
configUpdates = (args: ConfigUpdatesArgs, headers?: object): Promise<ConfigUpdatesReturn> => { | ||
return this.fetch( | ||
this.url('ConfigUpdates'), | ||
createHTTPRequest(args, headers)).then((res) => { | ||
return this.fetch(this.url('ConfigUpdates'), createHTTPRequest(args, headers)).then(res => { | ||
return buildResponse(res).then(_data => { | ||
return { | ||
updates: <Array<ConfigUpdate>>(_data.updates) | ||
updates: <Array<ConfigUpdate>>_data.updates | ||
} | ||
@@ -271,10 +250,8 @@ }) | ||
} | ||
migrations = (args: MigrationsArgs, headers?: object): Promise<MigrationsReturn> => { | ||
return this.fetch( | ||
this.url('Migrations'), | ||
createHTTPRequest(args, headers)).then((res) => { | ||
return this.fetch(this.url('Migrations'), createHTTPRequest(args, headers)).then(res => { | ||
return buildResponse(res).then(_data => { | ||
return { | ||
migrations: <{[key: string]: {[key: number]: {[key: string]: TransactionBundle}}}>(_data.migrations) | ||
migrations: <{ [key: string]: { [key: number]: { [key: string]: TransactionBundle } } }>_data.migrations | ||
} | ||
@@ -284,65 +261,48 @@ }) | ||
} | ||
saveConfig = (args: SaveConfigArgs, headers?: object): Promise<SaveConfigReturn> => { | ||
return this.fetch( | ||
this.url('SaveConfig'), | ||
createHTTPRequest(args, headers)).then((res) => { | ||
return this.fetch(this.url('SaveConfig'), createHTTPRequest(args, headers)).then(res => { | ||
return buildResponse(res).then(_data => { | ||
return { | ||
} | ||
return {} | ||
}) | ||
}) | ||
} | ||
saveWallet = (args: SaveWalletArgs, headers?: object): Promise<SaveWalletReturn> => { | ||
return this.fetch( | ||
this.url('SaveWallet'), | ||
createHTTPRequest(args, headers)).then((res) => { | ||
return this.fetch(this.url('SaveWallet'), createHTTPRequest(args, headers)).then(res => { | ||
return buildResponse(res).then(_data => { | ||
return { | ||
} | ||
return {} | ||
}) | ||
}) | ||
} | ||
saveSignature = (args: SaveSignatureArgs, headers?: object): Promise<SaveSignatureReturn> => { | ||
return this.fetch( | ||
this.url('SaveSignature'), | ||
createHTTPRequest(args, headers)).then((res) => { | ||
return this.fetch(this.url('SaveSignature'), createHTTPRequest(args, headers)).then(res => { | ||
return buildResponse(res).then(_data => { | ||
return { | ||
} | ||
return {} | ||
}) | ||
}) | ||
} | ||
saveSignerSignatures = (args: SaveSignerSignaturesArgs, headers?: object): Promise<SaveSignerSignaturesReturn> => { | ||
return this.fetch( | ||
this.url('SaveSignerSignatures'), | ||
createHTTPRequest(args, headers)).then((res) => { | ||
return this.fetch(this.url('SaveSignerSignatures'), createHTTPRequest(args, headers)).then(res => { | ||
return buildResponse(res).then(_data => { | ||
return { | ||
} | ||
return {} | ||
}) | ||
}) | ||
} | ||
saveMigration = (args: SaveMigrationArgs, headers?: object): Promise<SaveMigrationReturn> => { | ||
return this.fetch( | ||
this.url('SaveMigration'), | ||
createHTTPRequest(args, headers)).then((res) => { | ||
return this.fetch(this.url('SaveMigration'), createHTTPRequest(args, headers)).then(res => { | ||
return buildResponse(res).then(_data => { | ||
return { | ||
} | ||
return {} | ||
}) | ||
}) | ||
} | ||
} | ||
export interface WebRPCError extends Error { | ||
code: string | ||
msg: string | ||
status: number | ||
status: number | ||
} | ||
@@ -363,3 +323,3 @@ | ||
data = JSON.parse(text) | ||
} catch(err) { | ||
} catch (err) { | ||
throw { code: 'unknown', msg: `expecting JSON, got: ${text}`, status: res.status } as WebRPCError | ||
@@ -366,0 +326,0 @@ } |
@@ -1,6 +0,6 @@ | ||
import { commons, v1, v2 } from "@0xsequence/core" | ||
import { ethers } from "ethers" | ||
import { commons, v1, v2 } from '@0xsequence/core' | ||
import { ethers } from 'ethers' | ||
export type PlainNode = { | ||
left: string, | ||
left: string | ||
right: string | ||
@@ -10,4 +10,4 @@ } | ||
export type PlainNested = { | ||
weight: string, | ||
threshold: string, | ||
weight: string | ||
threshold: string | ||
tree: string | ||
@@ -17,5 +17,5 @@ } | ||
export type PlainV2Config = { | ||
version: 2, | ||
threshold: string, | ||
checkpoint: string, | ||
version: 2 | ||
threshold: string | ||
checkpoint: string | ||
tree: string | ||
@@ -52,3 +52,3 @@ } | ||
// counterfactual wallets | ||
loadCounterfactualWallet: (wallet: string) => Promise<{ imageHash: string, context: commons.context.WalletContext } | undefined> | ||
loadCounterfactualWallet: (wallet: string) => Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> | ||
saveCounterfactualWallet: (wallet: string, imageHash: string, context: commons.context.WalletContext) => Promise<void> | ||
@@ -66,4 +66,14 @@ | ||
// migrations | ||
loadMigrationsSubdigest: (wallet: string, fromVersion: number, toVersion: number) => Promise<{ subdigest: string, toImageHash: string }[]> | ||
saveMigrationsSubdigest: (wallet: string, fromVersion: number, toVersion: number, subdigest: string, toImageHash: string) => Promise<void> | ||
loadMigrationsSubdigest: ( | ||
wallet: string, | ||
fromVersion: number, | ||
toVersion: number | ||
) => Promise<{ subdigest: string; toImageHash: string }[]> | ||
saveMigrationsSubdigest: ( | ||
wallet: string, | ||
fromVersion: number, | ||
toVersion: number, | ||
subdigest: string, | ||
toImageHash: string | ||
) => Promise<void> | ||
} | ||
@@ -70,0 +80,0 @@ |
@@ -1,4 +0,4 @@ | ||
import { commons, v1, v2 } from "@0xsequence/core" | ||
import { ethers } from "ethers" | ||
import { PlainNested, PlainNode, PlainV2Config, TrackerStore } from "." | ||
import { commons, v1, v2 } from '@0xsequence/core' | ||
import { ethers } from 'ethers' | ||
import { PlainNested, PlainNode, PlainV2Config, TrackerStore } from '.' | ||
@@ -8,42 +8,42 @@ import { DBSchema, IDBPDatabase, openDB } from 'idb' | ||
export interface LocalTrackerDBSchema extends DBSchema { | ||
'configs': { | ||
key: string, | ||
configs: { | ||
key: string | ||
value: v1.config.WalletConfig | v2.config.WalletConfig | PlainV2Config | ||
}, | ||
'v2Nodes': { | ||
key: string, | ||
} | ||
v2Nodes: { | ||
key: string | ||
value: v2.config.Topology | PlainNode | PlainNested | ||
}, | ||
'counterfactualWallets': { | ||
key: string, | ||
} | ||
counterfactualWallets: { | ||
key: string | ||
value: { | ||
imageHash: string, | ||
imageHash: string | ||
context: commons.context.WalletContext | ||
} | ||
}, | ||
'payloads': { | ||
key: string, | ||
} | ||
payloads: { | ||
key: string | ||
value: commons.signature.SignedPayload | ||
}, | ||
'signatures': { | ||
key: string, // `${signer}-${subdigest}` | ||
} | ||
signatures: { | ||
key: string // `${signer}-${subdigest}` | ||
value: { | ||
signature: ethers.BytesLike | ||
signer: string | ||
}, | ||
} | ||
indexes: { | ||
'signer': string | ||
signer: string | ||
} | ||
}, | ||
'migrations': { | ||
key: string, | ||
} | ||
migrations: { | ||
key: string | ||
value: { | ||
wallet: string, | ||
fromVersion: number, | ||
toVersion: number, | ||
subdigest: string, | ||
wallet: string | ||
fromVersion: number | ||
toVersion: number | ||
subdigest: string | ||
toImageHash: string | ||
}, | ||
} | ||
indexes: { | ||
'jump': string // '${wallet}-${fromVersion}-${toVersion} | ||
jump: string // '${wallet}-${fromVersion}-${toVersion} | ||
} | ||
@@ -61,8 +61,3 @@ } | ||
if ( | ||
val._isBigNumber === true && | ||
val._hex !== undefined && | ||
typeof val._hex === 'string' && | ||
val._hex.length !== '' | ||
) { | ||
if (val._isBigNumber === true && val._hex !== undefined && typeof val._hex === 'string' && val._hex.length !== '') { | ||
// Entry is a big number | ||
@@ -72,3 +67,3 @@ result[key] = ethers.BigNumber.from(val) | ||
// Entry is an array, recurse | ||
result[key] = val.map((v) => recreateBigNumbers(v)) | ||
result[key] = val.map(v => recreateBigNumbers(v)) | ||
} else if (typeof val === 'object' && val !== null) { | ||
@@ -110,3 +105,3 @@ // Entry is another object, recurse | ||
} | ||
}, | ||
} | ||
}) | ||
@@ -116,15 +111,20 @@ return this._lazyDb | ||
loadConfig = async (imageHash: string): Promise<v1.config.WalletConfig | v2.config.WalletConfig | PlainV2Config | undefined> => { | ||
loadConfig = async ( | ||
imageHash: string | ||
): Promise<v1.config.WalletConfig | v2.config.WalletConfig | PlainV2Config | undefined> => { | ||
const db = await this.getDb() | ||
return db.get('configs', imageHash).then((c) => recreateBigNumbers(c)) | ||
return db.get('configs', imageHash).then(c => recreateBigNumbers(c)) | ||
} | ||
saveConfig = async (imageHash: string, config: v1.config.WalletConfig | v2.config.WalletConfig | PlainV2Config): Promise<void> => { | ||
saveConfig = async ( | ||
imageHash: string, | ||
config: v1.config.WalletConfig | v2.config.WalletConfig | PlainV2Config | ||
): Promise<void> => { | ||
const db = await this.getDb() | ||
await db.put('configs', config, imageHash) | ||
} | ||
loadV2Node = async (nodeHash: string): Promise<v2.config.Topology | PlainNode | PlainNested | undefined> => { | ||
const db = await this.getDb() | ||
return db.get('v2Nodes', nodeHash).then((c) => recreateBigNumbers(c)) | ||
return db.get('v2Nodes', nodeHash).then(c => recreateBigNumbers(c)) | ||
} | ||
@@ -137,3 +137,5 @@ | ||
loadCounterfactualWallet = async (wallet: string): Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> => { | ||
loadCounterfactualWallet = async ( | ||
wallet: string | ||
): Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> => { | ||
const db = await this.getDb() | ||
@@ -150,3 +152,3 @@ return db.get('counterfactualWallets', wallet) | ||
const db = await this.getDb() | ||
return db.get('payloads', subdigest).then((c) => recreateBigNumbers(c)) | ||
return db.get('payloads', subdigest).then(c => recreateBigNumbers(c)) | ||
} | ||
@@ -176,3 +178,7 @@ | ||
loadMigrationsSubdigest = async (wallet: string, fromVersion: number, toVersion: number): Promise<{subdigest: string, toImageHash: string}[]> => { | ||
loadMigrationsSubdigest = async ( | ||
wallet: string, | ||
fromVersion: number, | ||
toVersion: number | ||
): Promise<{ subdigest: string; toImageHash: string }[]> => { | ||
const db = await this.getDb() | ||
@@ -183,3 +189,9 @@ const index = await db.getAllFromIndex('migrations', 'jump', IDBKeyRange.only([wallet, fromVersion, toVersion])) | ||
saveMigrationsSubdigest = async (wallet: string, fromVersion: number, toVersion: number, subdigest: string, toImageHash: string): Promise<void> => { | ||
saveMigrationsSubdigest = async ( | ||
wallet: string, | ||
fromVersion: number, | ||
toVersion: number, | ||
subdigest: string, | ||
toImageHash: string | ||
): Promise<void> => { | ||
const db = await this.getDb() | ||
@@ -186,0 +198,0 @@ await db.put('migrations', { wallet, fromVersion, toVersion, subdigest, toImageHash }, subdigest) |
@@ -1,4 +0,4 @@ | ||
import { commons, v1, v2 } from "@0xsequence/core" | ||
import { ethers } from "ethers" | ||
import { PlainNested, PlainNode, PlainV2Config, TrackerStore } from "." | ||
import { commons, v1, v2 } from '@0xsequence/core' | ||
import { ethers } from 'ethers' | ||
import { PlainNested, PlainNode, PlainV2Config, TrackerStore } from '.' | ||
@@ -8,6 +8,8 @@ export class MemoryTrackerStore implements TrackerStore { | ||
private v2Nodes: { [nodeHash: string]: PlainNode | PlainNested | v2.config.Topology } = {} | ||
private counterfactualWallets: { [wallet: string]: { imageHash: string, context: commons.context.WalletContext } } = {} | ||
private counterfactualWallets: { [wallet: string]: { imageHash: string; context: commons.context.WalletContext } } = {} | ||
private payloads: { [subdigest: string]: commons.signature.SignedPayload } = {} | ||
private signatures: { [signer: string]: { [subdigest: string]: ethers.BytesLike } } = {} | ||
private migrations: { [wallet: string]: { [fromVersion: number]: { [toVersion: number]: { subdigest: string, toImageHash: string }[] } } } = {} | ||
private migrations: { | ||
[wallet: string]: { [fromVersion: number]: { [toVersion: number]: { subdigest: string; toImageHash: string }[] } } | ||
} = {} | ||
@@ -22,3 +24,3 @@ loadConfig = (imageHash: string): Promise<v1.config.WalletConfig | v2.config.WalletConfig | PlainV2Config | undefined> => { | ||
} | ||
loadV2Node = (nodeHash: string): Promise<v2.config.Topology | PlainNode | PlainNested | undefined> => { | ||
@@ -33,3 +35,5 @@ return Promise.resolve(this.v2Nodes[nodeHash]) | ||
loadCounterfactualWallet = (wallet: string): Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> => { | ||
loadCounterfactualWallet = ( | ||
wallet: string | ||
): Promise<{ imageHash: string; context: commons.context.WalletContext } | undefined> => { | ||
return Promise.resolve(this.counterfactualWallets[wallet]) | ||
@@ -66,7 +70,17 @@ } | ||
loadMigrationsSubdigest = (wallet: string, fromVersion: number, toVersion: number): Promise<{ subdigest: string, toImageHash: string }[]> => { | ||
loadMigrationsSubdigest = ( | ||
wallet: string, | ||
fromVersion: number, | ||
toVersion: number | ||
): Promise<{ subdigest: string; toImageHash: string }[]> => { | ||
return Promise.resolve(this.migrations[wallet]?.[fromVersion]?.[toVersion] || []) | ||
} | ||
saveMigrationsSubdigest = (wallet: string, fromVersion: number, toVersion: number, subdigest: string, toImageHash: string): Promise<void> => { | ||
saveMigrationsSubdigest = ( | ||
wallet: string, | ||
fromVersion: number, | ||
toVersion: number, | ||
subdigest: string, | ||
toImageHash: string | ||
): Promise<void> => { | ||
if (!this.migrations[wallet]) this.migrations[wallet] = {} | ||
@@ -73,0 +87,0 @@ if (!this.migrations[wallet][fromVersion]) this.migrations[wallet][fromVersion] = {} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
293971
7521
+ Added@0xsequence/abi@1.1.2(transitive)
+ Added@0xsequence/core@1.1.2(transitive)
+ Added@0xsequence/indexer@1.1.2(transitive)
+ Added@0xsequence/migration@1.1.2(transitive)
+ Added@0xsequence/network@1.1.2(transitive)
+ Added@0xsequence/relayer@1.1.2(transitive)
+ Added@0xsequence/replacer@1.1.2(transitive)
+ Added@0xsequence/signhub@1.1.2(transitive)
+ Added@0xsequence/utils@1.1.2(transitive)
+ Added@0xsequence/wallet@1.1.2(transitive)
- Removed@0xsequence/abi@1.1.1(transitive)
- Removed@0xsequence/core@1.1.1(transitive)
- Removed@0xsequence/indexer@1.1.1(transitive)
- Removed@0xsequence/migration@1.1.1(transitive)
- Removed@0xsequence/network@1.1.1(transitive)
- Removed@0xsequence/relayer@1.1.1(transitive)
- Removed@0xsequence/replacer@1.1.1(transitive)
- Removed@0xsequence/signhub@1.1.1(transitive)
- Removed@0xsequence/utils@1.1.1(transitive)
- Removed@0xsequence/wallet@1.1.1(transitive)
Updated@0xsequence/core@1.1.2
Updated@0xsequence/migration@1.1.2
Updated@0xsequence/replacer@1.1.2