Skip to content

Commit

Permalink
expose fe sdk method for proving and registering addr
Browse files Browse the repository at this point in the history
  • Loading branch information
luketchang committed Sep 6, 2023
1 parent 187b52c commit d805344
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 19 deletions.
2 changes: 1 addition & 1 deletion apps/snap/snap.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "Nocturne Snap",
"proposedName": "Nocturne Snap",
"source": {
"shasum": "JThkSvXYGlfw5CdeeE6K4I7YdtGRRoWOPYmEHyrqIkI=",
"shasum": "hubjXR9cnFgZTrAvDRy6hbR/vnXUe6GYy1DBknI0u0o=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
12 changes: 11 additions & 1 deletion apps/snap/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,18 @@ async function handleRpcRequest({
chainId,
registryAddress
);

const canonAddr = signer.canonicalAddress();
const registrySig = signer.sign(registryDigest);
return registrySig;
const spendPubkey = signer.spendPk;
const vkNonce = signer.vkNonce;
return {
canonAddr,
digest: registryDigest,
sig: registrySig,
spendPubkey,
vkNonce,
};
case "nocturne_signOperation":
console.log("Request params: ", request.params);

Expand Down
14 changes: 8 additions & 6 deletions packages/core/src/snapJsonRpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
PreSignOperation,
SignedOperation,
} from "./primitives";
import { NocturneSignature, ViewingKey } from "./crypto";
import { CanonAddress, NocturneSignature, SpendPk, ViewingKey } from "./crypto";

export interface SignCanonAddrRegistryEntry {
method: "nocturne_signCanonAddrRegistryEntry";
Expand All @@ -14,7 +14,13 @@ export interface SignCanonAddrRegistryEntry {
chainId: bigint;
registryAddress: string;
};
return: NocturneSignature;
return: {
canonAddr: CanonAddress;
digest: bigint;
sig: NocturneSignature;
spendPubkey: SpendPk;
vkNonce: bigint;
};
}

export interface SignOperationMethod {
Expand All @@ -34,10 +40,6 @@ export interface RequestViewingKeyMethod {
return: RequestViewingKeyMethodResponse;
}

export interface GetCanonAddrSigCheckProofInputsParams {
nonce: bigint;
}

export type RpcRequestMethod =
| SignCanonAddrRegistryEntry
| SignOperationMethod
Expand Down
89 changes: 78 additions & 11 deletions packages/frontend-sdk/src/sdk.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Erc20Config } from "@nocturne-xyz/config";
import {
CanonicalAddressRegistry,
CanonicalAddressRegistry__factory,
DepositManager,
DepositManager__factory,
Handler,
Expand Down Expand Up @@ -53,8 +55,14 @@ import {
BundlerOpTracker,
PreSignOperation,
CanonAddrSigCheckProofWithPublicSignals,
compressPoint,
SignCanonAddrRegistryEntry,
packToSolidityProof,
} from "@nocturne-xyz/core";
import { WasmCanonAddrSigCheckProver, WasmJoinSplitProver } from "@nocturne-xyz/local-prover";
import {
WasmCanonAddrSigCheckProver,
WasmJoinSplitProver,
} from "@nocturne-xyz/local-prover";
import {
OperationResult,
Client as UrqlClient,
Expand Down Expand Up @@ -100,8 +108,10 @@ const JOINSPLIT_WASM_PATH =
const JOINSPLIT_ZKEY_PATH =
"https://frontend-sdk-circuit-artifacts.s3.us-east-2.amazonaws.com/joinsplit/joinsplit.zkey";

const CANON_ADDR_SIG_CHECK_WASM_PATH = "https://frontend-sdk-circuit-artifacts.s3.us-east-2.amazonaws.com/canonAddrSigCheck/canonAddrSigCheck.wasm";
const CANON_ADDR_SIG_CHECK_ZKEY_PATH = "https://frontend-sdk-circuit-artifacts.s3.us-east-2.amazonaws.com/canonAddrSigCheck/canonAddrSigCheck.zkey";
const CANON_ADDR_SIG_CHECK_WASM_PATH =
"https://frontend-sdk-circuit-artifacts.s3.us-east-2.amazonaws.com/canonAddrSigCheck/canonAddrSigCheck.wasm";
const CANON_ADDR_SIG_CHECK_ZKEY_PATH =
"https://frontend-sdk-circuit-artifacts.s3.us-east-2.amazonaws.com/canonAddrSigCheck/canonAddrSigCheck.zkey";

export interface NocturneSdkOptions {
networkName?: SupportedNetwork;
Expand All @@ -124,6 +134,7 @@ export class NocturneSdk implements NocturneSdkApi {
protected signerThunk: Thunk<ethers.Signer>;
protected depositManagerContractThunk: Thunk<DepositManager>;
protected handlerContractThunk: Thunk<Handler>;
protected canonAddrRegistryThunk: Thunk<CanonicalAddressRegistry>;
protected clientThunk: Thunk<NocturneClient>;

// Caller MUST conform to EIP-1193 spec (window.ethereum) https://eips.ethereum.org/EIPS/eip-1193
Expand Down Expand Up @@ -179,13 +190,18 @@ export class NocturneSdk implements NocturneSdkApi {
await this.signerThunk()
)
);
this.canonAddrRegistryThunk = thunk(async () =>
CanonicalAddressRegistry__factory.connect(
this.config.config.canonicalAddressRegistryAddress(),
await this.signerThunk()
)
);

this.urqlClient = new UrqlClient({
url: this.endpoints.subgraphEndpoint,
exchanges: [fetchExchange],
});

// TODO: add IdbKVStore + make this actually persistent
const kv = new IdbKvStore(`nocturne-fe-sdk-${networkName}`);
this.db = new NocturneDB(kv);

Expand Down Expand Up @@ -284,6 +300,46 @@ export class NocturneSdk implements NocturneSdkApi {
);
}

// TODO: use this method in interface
async registerCanonicalAddress(): Promise<ethers.ContractTransaction> {
const ethSigner = await this.getWindowSigner();
const client = await this.clientThunk();
const registry = await this.canonAddrRegistryThunk();
const prover = await this.canonAddrSigCheckProverThunk();

const canonAddr = client.viewer.canonicalAddress();
const compressedCanonAddr = compressPoint(canonAddr);
const nonce = (
await registry._compressedCanonAddrToNonce(compressedCanonAddr)
).toBigInt();

const { digest, sig, spendPubkey, vkNonce } =
await this.invokeSnap<SignCanonAddrRegistryEntry>({
method: "nocturne_signCanonAddrRegistryEntry",
params: {
entry: {
ethAddress: await ethSigner.getAddress(),
perCanonAddrNonce: nonce,
},
chainId: BigInt(this.config.config.contracts.network.chainId),
registryAddress: registry.address,
},
});

const { proof } = await prover.proveCanonAddrSigCheck({
canonAddr,
msg: digest,
sig,
spendPubkey,
vkNonce,
});

return registry.setCanonAddr(
compressedCanonAddr,
packToSolidityProof(proof)
);
}

async initiateErc20Deposits(
erc20Address: Address,
values: bigint[],
Expand Down Expand Up @@ -463,14 +519,16 @@ export class NocturneSdk implements NocturneSdkApi {
* @param operationRequest Operation request
*/
async signOperationRequest(
operationRequest: OperationRequestWithMetadata,
operationRequest: OperationRequestWithMetadata
): Promise<SignedOperation> {
console.log("[fe-sdk] metadata:", operationRequest.meta);
const client = await this.clientThunk();

// NOTE: we should never end up in situation where this is called before normal nocturne_sync, otherwise there will be long delay
const warnTimeout = setTimeout(() => {
console.warn("[fe-sdk] the SDK has not yet been synced. This may cause a long delay until `signOperation` returns. It's strongly reccomended to explicitly use `sync` or `syncWithProgress` to ensure the SDK is fully synced before calling `signOperation`");
console.warn(
"[fe-sdk] the SDK has not yet been synced. This may cause a long delay until `signOperation` returns. It's strongly reccomended to explicitly use `sync` or `syncWithProgress` to ensure the SDK is fully synced before calling `signOperation`"
);
}, 5000);
await this.syncMutex.runExclusive(async () => await client.sync());
clearTimeout(warnTimeout);
Expand Down Expand Up @@ -620,7 +678,7 @@ export class NocturneSdk implements NocturneSdkApi {
async getAllBalances(opts?: GetBalanceOpts): Promise<AssetWithBalance[]> {
console.log("[fe-sdk] getAllBalances with params:", opts);
const client = await this.clientThunk();

await this.syncMutex.runExclusive(async () => await client.sync());
return await client.getAllAssetBalances(opts);
}
Expand All @@ -639,7 +697,8 @@ export class NocturneSdk implements NocturneSdkApi {

async getInFlightOperations(): Promise<OperationHandle[]> {
const client = await this.clientThunk();
const opDigestsWithMetadata = await client.getAllOptimisticOpDigestsWithMetadata();
const opDigestsWithMetadata =
await client.getAllOptimisticOpDigestsWithMetadata();
const operationHandles = opDigestsWithMetadata.map(
({ opDigest: digest, metadata }) => {
return {
Expand Down Expand Up @@ -669,7 +728,10 @@ export class NocturneSdk implements NocturneSdkApi {
);

let closed = false;
const generator = async function* (sdk: NocturneSdk, client: NocturneClient) {
const generator = async function* (
sdk: NocturneSdk,
client: NocturneClient
) {
let count = 0;
while (!closed && latestSyncedMerkleIndex < latestMerkleIndexOnChain) {
latestSyncedMerkleIndex = (await client.sync(syncOpts)) ?? 0;
Expand Down Expand Up @@ -724,13 +786,18 @@ export class NocturneSdk implements NocturneSdkApi {
let latestSyncedMerkleIndex: number | undefined;
try {
const client = await this.clientThunk();
latestSyncedMerkleIndex = await this.syncMutex.runExclusive(async () => await client.sync(syncOpts));
latestSyncedMerkleIndex = await this.syncMutex.runExclusive(
async () => await client.sync(syncOpts)
);
await client.updateOptimisticNullifiers();
} catch (e) {
console.log("Error syncing notes: ", e);
throw e;
}
console.log("[sync] FE-sdk latestSyncedMerkleIndex, ", latestSyncedMerkleIndex);
console.log(
"[sync] FE-sdk latestSyncedMerkleIndex, ",
latestSyncedMerkleIndex
);
return latestSyncedMerkleIndex;
}

Expand Down

0 comments on commit d805344

Please sign in to comment.