@zerc20/wallet-sdk 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/accountId.d.ts +5 -0
- package/dist/accountId.js +19 -0
- package/dist/accountId.js.map +1 -0
- package/dist/chain.d.ts +85 -9
- package/dist/chain.js +60 -33
- package/dist/chain.js.map +1 -1
- package/dist/context.d.ts +14 -6
- package/dist/context.js +17 -3
- package/dist/context.js.map +1 -1
- package/dist/core.d.ts +35 -5
- package/dist/core.js +95 -23
- package/dist/core.js.map +1 -1
- package/dist/errors.d.ts +2 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/pos.d.ts +7 -1
- package/dist/pos.js +213 -55
- package/dist/pos.js.map +1 -1
- package/dist/rageExit.d.ts +27 -4
- package/dist/rageExit.js +160 -49
- package/dist/rageExit.js.map +1 -1
- package/dist/seed.d.ts +4 -0
- package/dist/seed.js +13 -1
- package/dist/seed.js.map +1 -1
- package/dist/servers.d.ts +2 -0
- package/dist/servers.js +1 -0
- package/dist/servers.js.map +1 -1
- package/dist/services.d.ts +11 -4
- package/dist/services.js +26 -7
- package/dist/services.js.map +1 -1
- package/dist/spend.d.ts +30 -9
- package/dist/spend.js +46 -17
- package/dist/spend.js.map +1 -1
- package/dist/state.d.ts +21 -0
- package/dist/state.js.map +1 -1
- package/dist/sync.d.ts +10 -5
- package/dist/sync.js +53 -19
- package/dist/sync.js.map +1 -1
- package/dist/viewKey.d.ts +14 -0
- package/dist/viewKey.js +45 -0
- package/dist/viewKey.js.map +1 -0
- package/dist/wallet.d.ts +109 -16
- package/dist/wallet.js +291 -85
- package/dist/wallet.js.map +1 -1
- package/package.json +3 -2
- package/src/accountId.ts +22 -0
- package/src/chain.ts +95 -49
- package/src/context.ts +35 -8
- package/src/core.ts +109 -24
- package/src/errors.ts +2 -0
- package/src/index.ts +18 -2
- package/src/pos.ts +240 -61
- package/src/rageExit.ts +237 -61
- package/src/seed.ts +24 -1
- package/src/servers.ts +4 -1
- package/src/services.ts +28 -15
- package/src/spend.ts +58 -23
- package/src/state.ts +25 -1
- package/src/sync.ts +57 -20
- package/src/viewKey.ts +49 -0
- package/src/wallet.ts +387 -106
- package/wasm/zerc20_wallet_core.d.ts +8 -1
- package/wasm/zerc20_wallet_core.js +31 -1
- package/wasm/zerc20_wallet_core_bg.wasm +0 -0
- package/wasm/zerc20_wallet_core_bg.wasm.d.ts +1 -0
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ const wallet = await Wallet.open({ network, walletClient, seed, persist: { load,
|
|
|
19
19
|
await wallet.sync();
|
|
20
20
|
wallet.balances();
|
|
21
21
|
const q = await wallet.fees({ kind: 'send', token, amount });
|
|
22
|
-
await (await wallet.send({ to: '
|
|
22
|
+
await (await wallet.send({ to: 'zerc20id1…', token, amount, maxFee: q.fee })).wait();
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
## License
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type Address } from 'viem';
|
|
2
|
+
/** `address` as its zERC20 ID: checksummed text (bech32m, `zerc20id1…`) of its 20 bytes. */
|
|
3
|
+
export declare const accountId: (address: Address) => string;
|
|
4
|
+
/** The account `text` is the zERC20 ID of, or `null` if it is not one. */
|
|
5
|
+
export declare function idAccount(text: string): Address | null;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// A zERC20 ID: an account's address as text that no other wallet or exchange takes for an address, so that a payer
|
|
2
|
+
// pays the account privately, as only a zERC20 wallet does, and never by a public transfer to the address, which this
|
|
3
|
+
// wallet does not hold.
|
|
4
|
+
import { bech32m } from '@scure/base';
|
|
5
|
+
import { bytesToHex, getAddress, hexToBytes } from 'viem';
|
|
6
|
+
const PREFIX = 'zerc20id';
|
|
7
|
+
/** `address` as its zERC20 ID: checksummed text (bech32m, `zerc20id1…`) of its 20 bytes. */
|
|
8
|
+
export const accountId = (address) => bech32m.encode(PREFIX, bech32m.toWords(hexToBytes(address)), false);
|
|
9
|
+
/** The account `text` is the zERC20 ID of, or `null` if it is not one. */
|
|
10
|
+
export function idAccount(text) {
|
|
11
|
+
try {
|
|
12
|
+
const { prefix, bytes } = bech32m.decodeToBytes(text.trim());
|
|
13
|
+
return prefix === PREFIX && bytes.length === 20 ? getAddress(bytesToHex(bytes)) : null;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=accountId.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accountId.js","sourceRoot":"","sources":["../src/accountId.ts"],"names":[],"mappings":"AAAA,mHAAmH;AACnH,sHAAsH;AACtH,wBAAwB;AAExB,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAgB,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAExE,MAAM,MAAM,GAAG,UAAU,CAAC;AAE1B,4FAA4F;AAC5F,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,OAAgB,EAAU,EAAE,CACpD,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAEtE,0EAA0E;AAC1E,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7D,OAAO,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/dist/chain.d.ts
CHANGED
|
@@ -282,6 +282,41 @@ export declare const depositFactoryAbi: readonly [{
|
|
|
282
282
|
}, {
|
|
283
283
|
readonly type: "address";
|
|
284
284
|
readonly name: "refundAddress";
|
|
285
|
+
}, {
|
|
286
|
+
readonly type: "address";
|
|
287
|
+
readonly name: "refundSigner";
|
|
288
|
+
}, {
|
|
289
|
+
readonly type: "address";
|
|
290
|
+
readonly name: "feeRecipient";
|
|
291
|
+
}, {
|
|
292
|
+
readonly type: "uint256";
|
|
293
|
+
readonly name: "fee";
|
|
294
|
+
}, {
|
|
295
|
+
readonly type: "address";
|
|
296
|
+
readonly name: "referrer";
|
|
297
|
+
}, {
|
|
298
|
+
readonly type: "uint16";
|
|
299
|
+
readonly name: "referralBps";
|
|
300
|
+
}];
|
|
301
|
+
readonly outputs: readonly [{
|
|
302
|
+
readonly type: "address";
|
|
303
|
+
}];
|
|
304
|
+
}, {
|
|
305
|
+
readonly name: "flush";
|
|
306
|
+
readonly type: "function";
|
|
307
|
+
readonly stateMutability: "nonpayable";
|
|
308
|
+
readonly inputs: readonly [{
|
|
309
|
+
readonly type: "address";
|
|
310
|
+
readonly name: "token";
|
|
311
|
+
}, {
|
|
312
|
+
readonly type: "address";
|
|
313
|
+
readonly name: "burnAddress";
|
|
314
|
+
}, {
|
|
315
|
+
readonly type: "address";
|
|
316
|
+
readonly name: "refundAddress";
|
|
317
|
+
}, {
|
|
318
|
+
readonly type: "address";
|
|
319
|
+
readonly name: "refundSigner";
|
|
285
320
|
}, {
|
|
286
321
|
readonly type: "address";
|
|
287
322
|
readonly name: "feeRecipient";
|
|
@@ -299,6 +334,18 @@ export declare const depositFactoryAbi: readonly [{
|
|
|
299
334
|
readonly type: "address";
|
|
300
335
|
}];
|
|
301
336
|
}];
|
|
337
|
+
/** Where a deposit address sends back what it cannot wrap, and a rage exit's refund: a fixed address, which anyone may
|
|
338
|
+
* refund to, or wherever the key at `signer` signs for each refund (`DepositAddress.refundTo`). */
|
|
339
|
+
export type Refund = {
|
|
340
|
+
address: Address;
|
|
341
|
+
} | {
|
|
342
|
+
signer: Address;
|
|
343
|
+
};
|
|
344
|
+
/** What the factory derives a deposit address from, in the order its `predict` and `flush` take it. */
|
|
345
|
+
export type FactoryArgs = readonly [Address, Hex, Address, Address, Address, bigint, Address, number];
|
|
346
|
+
/** `FactoryArgs` for a deposit address of `token` into `burnAddress` whose refunds go as `refund` says, and whose flush
|
|
347
|
+
* pays `fee` to `feeRecipient` and `referralBps` of the rest to `referrer`. */
|
|
348
|
+
export declare const factoryArgs: (token: Address, burnAddress: Hex, refund: Refund, feeRecipient: Address, fee: bigint, referrer: Address, referralBps: number) => FactoryArgs;
|
|
302
349
|
/** The factory's `MAX_REFERRAL_BPS`: the most of a deposit, after the relayer's fee, that a referrer can take. */
|
|
303
350
|
export declare const MAX_REFERRAL_BPS = 300;
|
|
304
351
|
/** An app that hands out deposit addresses and takes `bps` of each payment to them, of what is left after the relayer's
|
|
@@ -316,7 +363,30 @@ export declare const depositAddressAbi: readonly [{
|
|
|
316
363
|
readonly name: "asset";
|
|
317
364
|
}];
|
|
318
365
|
readonly outputs: readonly [];
|
|
366
|
+
}, {
|
|
367
|
+
readonly name: "refundTo";
|
|
368
|
+
readonly type: "function";
|
|
369
|
+
readonly stateMutability: "nonpayable";
|
|
370
|
+
readonly inputs: readonly [{
|
|
371
|
+
readonly type: "address";
|
|
372
|
+
readonly name: "asset";
|
|
373
|
+
}, {
|
|
374
|
+
readonly type: "address";
|
|
375
|
+
readonly name: "to";
|
|
376
|
+
}, {
|
|
377
|
+
readonly type: "uint256";
|
|
378
|
+
readonly name: "deadline";
|
|
379
|
+
}, {
|
|
380
|
+
readonly type: "bytes";
|
|
381
|
+
readonly name: "signature";
|
|
382
|
+
}];
|
|
383
|
+
readonly outputs: readonly [];
|
|
319
384
|
}];
|
|
385
|
+
/** What a deposit address's refund signer signs to send its balance of `asset` to `to` until `deadline` (Unix seconds),
|
|
386
|
+
* as an EIP-191 message: the chain and the address are in it, so it moves nothing at the same address elsewhere. */
|
|
387
|
+
export declare const refundDigest: (chainId: bigint, depositAddress: Address, asset: Address, to: Address, deadline: bigint) => `0x${string}`;
|
|
388
|
+
/** Multicall3, at the address it has on every chain the deposit relayer serves: it puts calls in one transaction. */
|
|
389
|
+
export declare const MULTICALL3: Address;
|
|
320
390
|
/** The native asset's stand-in for `underlyingAsset`. */
|
|
321
391
|
export declare const NATIVE: Address;
|
|
322
392
|
/** `Protocol.UNWRAP_INTENT`: the `withdrawIntent` that pays a withdrawal out as the underlying asset. The EIP-712 struct
|
|
@@ -333,21 +403,25 @@ export interface Token {
|
|
|
333
403
|
symbol: string;
|
|
334
404
|
decimals: number;
|
|
335
405
|
}
|
|
406
|
+
/** A transport to a chain's RPC (`url`, or the chain's own) that waits out its rate limit. A public RPC turns calls
|
|
407
|
+
* away beyond some per second (Tenderly's gateways, about five `eth_call`s), which a sync and a deposit together pass;
|
|
408
|
+
* viem retries a refusal, but its default three retries give up within the second the limit counts. Five wait 0.15 s,
|
|
409
|
+
* doubling, 4.65 s in all. */
|
|
410
|
+
export declare const rpcTransport: (url?: string) => import("viem").HttpTransport<undefined, false>;
|
|
336
411
|
export declare class Chain {
|
|
337
412
|
#private;
|
|
338
413
|
readonly config: ChainConfig;
|
|
339
414
|
readonly client: PublicClient;
|
|
340
415
|
constructor(config: ChainConfig);
|
|
341
416
|
get chainId(): bigint;
|
|
342
|
-
ledger()
|
|
343
|
-
/** The deposit address the factory deploys for `
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
*
|
|
348
|
-
*
|
|
349
|
-
|
|
350
|
-
depositAddressRefund(address: Address, token: Address, burnAddress: Hex): Promise<Address | null>;
|
|
417
|
+
readonly ledger: () => Promise<`0x${string}`>;
|
|
418
|
+
/** The deposit address the factory deploys for `args`. */
|
|
419
|
+
predictDepositAddress(args: FactoryArgs): Promise<Address>;
|
|
420
|
+
/** Where `address` refunds to if it is a deployed deposit address for `token` and `burnAddress`, whatever its refund,
|
|
421
|
+
* fee and referral; null if it is not one. A clone's code ends with its immutable args,
|
|
422
|
+
* `abi.encode(token, burnAddress, refundAddress, refundSigner, feeRecipient, fee, referrer, referralBps)`; the
|
|
423
|
+
* factory's address for them confirms it, so code made to look like one does not pass. */
|
|
424
|
+
depositAddressRefund(address: Address, token: Address, burnAddress: Hex): Promise<Refund | null>;
|
|
351
425
|
/** Whether the ledger accepts `root` as the tree at `size` leaves. */
|
|
352
426
|
provedRoot(size: number, root: Hex): Promise<boolean>;
|
|
353
427
|
/** `2^64 - 1`, unless the ledger is in an emergency: then it accepts no root above it, and proves none. */
|
|
@@ -356,4 +430,6 @@ export declare class Chain {
|
|
|
356
430
|
withdrawFee(tokenId: number, amount: bigint): Promise<bigint>;
|
|
357
431
|
/** Every token the factory has registered, read once and then only the new ones. */
|
|
358
432
|
tokens(): Promise<Token[]>;
|
|
433
|
+
/** The tokens as `tokens()` last read them, without reading again. */
|
|
434
|
+
get known(): Token[];
|
|
359
435
|
}
|
package/dist/chain.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// What a wallet reads from the chain itself, through its own RPC: roots are taken from here, never from a server.
|
|
2
|
-
import { createPublicClient, decodeAbiParameters, http, keccak256, numberToHex, parseAbi, size, slice, toHex, zeroAddress, } from 'viem';
|
|
2
|
+
import { createPublicClient, decodeAbiParameters, encodeAbiParameters, http, keccak256, numberToHex, parseAbi, parseAbiParameters, size, slice, toHex, zeroAddress, } from 'viem';
|
|
3
3
|
export const verifierAbi = parseAbi([
|
|
4
4
|
'function ledger() view returns (address)',
|
|
5
5
|
'function factory() view returns (address)',
|
|
@@ -35,64 +35,91 @@ export const erc20Abi = parseAbi([
|
|
|
35
35
|
'function transfer(address to, uint256 amount) returns (bool)',
|
|
36
36
|
]);
|
|
37
37
|
export const depositFactoryAbi = parseAbi([
|
|
38
|
-
'function predict(address token, address burnAddress, address refundAddress, address feeRecipient, uint256 fee, address referrer, uint16 referralBps) view returns (address)',
|
|
38
|
+
'function predict(address token, address burnAddress, address refundAddress, address refundSigner, address feeRecipient, uint256 fee, address referrer, uint16 referralBps) view returns (address)',
|
|
39
|
+
'function flush(address token, address burnAddress, address refundAddress, address refundSigner, address feeRecipient, uint256 fee, address referrer, uint16 referralBps) returns (address)',
|
|
39
40
|
]);
|
|
41
|
+
const refundArgs = (refund) => 'address' in refund ? [refund.address, zeroAddress] : [zeroAddress, refund.signer];
|
|
42
|
+
/** `FactoryArgs` for a deposit address of `token` into `burnAddress` whose refunds go as `refund` says, and whose flush
|
|
43
|
+
* pays `fee` to `feeRecipient` and `referralBps` of the rest to `referrer`. */
|
|
44
|
+
export const factoryArgs = (token, burnAddress, refund, feeRecipient, fee, referrer, referralBps) => [token, burnAddress, ...refundArgs(refund), feeRecipient, fee, referrer, referralBps];
|
|
40
45
|
/** The factory's `MAX_REFERRAL_BPS`: the most of a deposit, after the relayer's fee, that a referrer can take. */
|
|
41
46
|
export const MAX_REFERRAL_BPS = 300;
|
|
42
|
-
export const depositAddressAbi = parseAbi([
|
|
47
|
+
export const depositAddressAbi = parseAbi([
|
|
48
|
+
'function refund(address asset)',
|
|
49
|
+
'function refundTo(address asset, address to, uint256 deadline, bytes signature)',
|
|
50
|
+
]);
|
|
51
|
+
/** What a deposit address's refund signer signs to send its balance of `asset` to `to` until `deadline` (Unix seconds),
|
|
52
|
+
* as an EIP-191 message: the chain and the address are in it, so it moves nothing at the same address elsewhere. */
|
|
53
|
+
export const refundDigest = (chainId, depositAddress, asset, to, deadline) => keccak256(encodeAbiParameters(parseAbiParameters('uint256, address, address, address, uint256'), [
|
|
54
|
+
chainId,
|
|
55
|
+
depositAddress,
|
|
56
|
+
asset,
|
|
57
|
+
to,
|
|
58
|
+
deadline,
|
|
59
|
+
]));
|
|
60
|
+
/** Multicall3, at the address it has on every chain the deposit relayer serves: it puts calls in one transaction. */
|
|
61
|
+
export const MULTICALL3 = '0xcA11bde05977b3631167028862bE2a173976CA11';
|
|
43
62
|
/** The native asset's stand-in for `underlyingAsset`. */
|
|
44
63
|
export const NATIVE = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';
|
|
45
64
|
/** `Protocol.UNWRAP_INTENT`: the `withdrawIntent` that pays a withdrawal out as the underlying asset. The EIP-712 struct
|
|
46
65
|
* hash of `Unwrap()`, reduced into the BN254 field. */
|
|
47
66
|
export const UNWRAP_INTENT = BigInt(keccak256(keccak256(toHex('Unwrap()')))) %
|
|
48
67
|
21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
68
|
+
/** A transport to a chain's RPC (`url`, or the chain's own) that waits out its rate limit. A public RPC turns calls
|
|
69
|
+
* away beyond some per second (Tenderly's gateways, about five `eth_call`s), which a sync and a deposit together pass;
|
|
70
|
+
* viem retries a refusal, but its default three retries give up within the second the limit counts. Five wait 0.15 s,
|
|
71
|
+
* doubling, 4.65 s in all. */
|
|
72
|
+
export const rpcTransport = (url) => http(url, { retryCount: 5 });
|
|
73
|
+
/** `read`, made once and then kept. A read that fails is not kept: the next call reads again, rather than failing for
|
|
74
|
+
* as long as the wallet is open. */
|
|
75
|
+
function once(read) {
|
|
76
|
+
let kept;
|
|
77
|
+
return () => (kept ??= read().catch((e) => {
|
|
78
|
+
kept = undefined;
|
|
79
|
+
throw e;
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
49
82
|
export class Chain {
|
|
50
83
|
config;
|
|
51
84
|
client;
|
|
52
|
-
#
|
|
53
|
-
#tokens;
|
|
85
|
+
#tokens = [];
|
|
54
86
|
constructor(config) {
|
|
55
87
|
this.config = config;
|
|
56
|
-
this.client = createPublicClient({ transport:
|
|
88
|
+
this.client = createPublicClient({ transport: rpcTransport(config.rpcUrl) });
|
|
57
89
|
}
|
|
58
90
|
get chainId() {
|
|
59
91
|
return this.config.chainId;
|
|
60
92
|
}
|
|
61
|
-
ledger
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
});
|
|
67
|
-
return this.#ledger;
|
|
68
|
-
}
|
|
69
|
-
/** The deposit address the factory deploys for `token`, `burnAddress` and `refundAddress`, whose flush pays `fee`
|
|
70
|
-
* to `feeRecipient` and `referralBps` of the rest to `referrer`. */
|
|
71
|
-
predictDepositAddress(token, burnAddress, refundAddress, feeRecipient, fee, referrer, referralBps) {
|
|
93
|
+
// the verifier's ledger and token factory are set once, as it is initialized
|
|
94
|
+
ledger = once(() => this.client.readContract({ address: this.config.verifier, abi: verifierAbi, functionName: 'ledger' }));
|
|
95
|
+
#factory = once(() => this.client.readContract({ address: this.config.verifier, abi: verifierAbi, functionName: 'factory' }));
|
|
96
|
+
/** The deposit address the factory deploys for `args`. */
|
|
97
|
+
predictDepositAddress(args) {
|
|
72
98
|
return this.client.readContract({
|
|
73
99
|
address: this.config.depositAddressFactory,
|
|
74
100
|
abi: depositFactoryAbi,
|
|
75
101
|
functionName: 'predict',
|
|
76
|
-
args
|
|
102
|
+
args,
|
|
77
103
|
});
|
|
78
104
|
}
|
|
79
|
-
/**
|
|
80
|
-
*
|
|
81
|
-
* `abi.encode(token, burnAddress, refundAddress, feeRecipient, fee, referrer, referralBps)`; the
|
|
82
|
-
* for them confirms it, so code made to look like one does not pass. */
|
|
105
|
+
/** Where `address` refunds to if it is a deployed deposit address for `token` and `burnAddress`, whatever its refund,
|
|
106
|
+
* fee and referral; null if it is not one. A clone's code ends with its immutable args,
|
|
107
|
+
* `abi.encode(token, burnAddress, refundAddress, refundSigner, feeRecipient, fee, referrer, referralBps)`; the
|
|
108
|
+
* factory's address for them confirms it, so code made to look like one does not pass. */
|
|
83
109
|
async depositAddressRefund(address, token, burnAddress) {
|
|
84
110
|
const code = await this.client.getCode({ address });
|
|
85
|
-
if (!code || size(code) <
|
|
111
|
+
if (!code || size(code) < 256)
|
|
86
112
|
return null;
|
|
87
113
|
// the uint16 read as a whole word, so code made to look like a clone cannot make the decoding throw
|
|
88
|
-
const [refundAddress, feeRecipient, fee, referrer, referralBps] = decodeAbiParameters(
|
|
114
|
+
const [refundAddress, refundSigner, feeRecipient, fee, referrer, referralBps] = decodeAbiParameters(parseAbiParameters('address, address, address, uint256, address, uint256'), slice(code, size(code) - 192));
|
|
89
115
|
// predict would revert
|
|
90
|
-
if (refundAddress === zeroAddress || feeRecipient === zeroAddress)
|
|
116
|
+
if ((refundAddress === zeroAddress) === (refundSigner === zeroAddress) || feeRecipient === zeroAddress)
|
|
91
117
|
return null;
|
|
92
118
|
if (referralBps > MAX_REFERRAL_BPS || (referrer === zeroAddress && referralBps !== 0n))
|
|
93
119
|
return null;
|
|
94
|
-
const
|
|
95
|
-
|
|
120
|
+
const refund = refundAddress === zeroAddress ? { signer: refundSigner } : { address: refundAddress };
|
|
121
|
+
const expected = await this.predictDepositAddress(factoryArgs(token, burnAddress, refund, feeRecipient, fee, referrer, Number(referralBps)));
|
|
122
|
+
return expected.toLowerCase() === address.toLowerCase() ? refund : null;
|
|
96
123
|
}
|
|
97
124
|
/** Whether the ledger accepts `root` as the tree at `size` leaves. */
|
|
98
125
|
async provedRoot(size, root) {
|
|
@@ -125,13 +152,9 @@ export class Chain {
|
|
|
125
152
|
}
|
|
126
153
|
/** Every token the factory has registered, read once and then only the new ones. */
|
|
127
154
|
async tokens() {
|
|
128
|
-
const factory = await this
|
|
129
|
-
address: this.config.verifier,
|
|
130
|
-
abi: verifierAbi,
|
|
131
|
-
functionName: 'factory',
|
|
132
|
-
});
|
|
155
|
+
const factory = await this.#factory();
|
|
133
156
|
const count = await this.client.readContract({ address: factory, abi: factoryAbi, functionName: 'tokenCount' });
|
|
134
|
-
const known = this.#tokens
|
|
157
|
+
const known = this.#tokens;
|
|
135
158
|
const fresh = await Promise.all(Array.from({ length: count - known.length }, async (_, i) => {
|
|
136
159
|
const tokenId = known.length + i + 1;
|
|
137
160
|
const address = await this.client.readContract({
|
|
@@ -151,5 +174,9 @@ export class Chain {
|
|
|
151
174
|
this.#tokens = [...known, ...fresh];
|
|
152
175
|
return this.#tokens;
|
|
153
176
|
}
|
|
177
|
+
/** The tokens as `tokens()` last read them, without reading again. */
|
|
178
|
+
get known() {
|
|
179
|
+
return this.#tokens;
|
|
180
|
+
}
|
|
154
181
|
}
|
|
155
182
|
//# sourceMappingURL=chain.js.map
|
package/dist/chain.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chain.js","sourceRoot":"","sources":["../src/chain.ts"],"names":[],"mappings":"AAAA,kHAAkH;AAElH,OAAO,EAIL,kBAAkB,EAClB,mBAAmB,EACnB,IAAI,EACJ,SAAS,EACT,WAAW,EACX,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,KAAK,EACL,WAAW,GACZ,MAAM,MAAM,CAAC;AAGd,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC;IAClC,0CAA0C;IAC1C,2CAA2C;IAC3C,iDAAiD;IACjD,6EAA6E;IAC7E,yEAAyE;IACzE,gQAAgQ;IAChQ,4IAA4I;IAC5I,4CAA4C;CAC7C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,QAAQ,CAAC;IAChC,sEAAsE;IACtE,wCAAwC;IACxC,iEAAiE;IACjE,wEAAwE;IACxE,oGAAoG;IACpG,kGAAkG;CACnG,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC;IACjC,6CAA6C;IAC7C,2DAA2D;CAC5D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC;IAC/B,yCAAyC;IACzC,0CAA0C;IAC1C,mDAAmD;IACnD,yDAAyD;CAC1D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC;IAC/B,0DAA0D;IAC1D,2EAA2E;IAC3E,kEAAkE;IAClE,8DAA8D;CAC/D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACxC,
|
|
1
|
+
{"version":3,"file":"chain.js","sourceRoot":"","sources":["../src/chain.ts"],"names":[],"mappings":"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"}
|
package/dist/context.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CanisterClient, ViewKey } from '@zerc20/storage-sdk';
|
|
2
|
-
import { type Account, type Hex, type WalletClient } from 'viem';
|
|
3
|
-
import type
|
|
2
|
+
import { type Account, type Address, type Hex, type LocalAccount, type WalletClient } from 'viem';
|
|
3
|
+
import { type Chain } from './chain.js';
|
|
4
4
|
import type { ChainConfig, Network } from './network.js';
|
|
5
5
|
import type { Asp, Indexer } from './servers.js';
|
|
6
6
|
import type { ChainState, WalletState } from './state.js';
|
|
@@ -19,14 +19,18 @@ export interface SpendKey {
|
|
|
19
19
|
nullifyingKey: Hex;
|
|
20
20
|
}
|
|
21
21
|
/** What a sync needs of a key: its public key and nullifying key, which find and follow what it owns but spend none of
|
|
22
|
-
* it. */
|
|
23
|
-
export type Owner = Pick<SpendKey, 'publicKey' | 'nullifyingKey'>;
|
|
22
|
+
* it, and the signing key's hash, which with the nullifying key makes the public key. */
|
|
23
|
+
export type Owner = Pick<SpendKey, 'authKeyHash' | 'publicKey' | 'nullifyingKey'>;
|
|
24
24
|
export interface Ctx {
|
|
25
25
|
network: Network;
|
|
26
|
-
/** The root of every key. Opened with a function for it, held only while something needs it;
|
|
26
|
+
/** The root of every key. Opened with a function for it, held only while something needs it; watching, never;
|
|
27
|
+
* otherwise always. */
|
|
27
28
|
seed: Uint8Array | null;
|
|
28
|
-
/** The owners derived while the seed was held, by key: the wallet's own (`''`) and each
|
|
29
|
+
/** The owners derived while the seed was held, or given by a view key, by key: the wallet's own (`''`) and each
|
|
30
|
+
* receive code's. */
|
|
29
31
|
owners: Map<string, Owner>;
|
|
32
|
+
/** The refund signers' addresses derived while the seed was held, by receive code (`refundSigner`). */
|
|
33
|
+
refundSigners: Map<string, Address>;
|
|
30
34
|
address: Hex;
|
|
31
35
|
/** The account that holds the public funds, and signs for them. */
|
|
32
36
|
account: Account;
|
|
@@ -54,6 +58,10 @@ export declare function spendKey(ctx: Ctx, code?: CodeId): SpendKey;
|
|
|
54
58
|
/** `spendKey`'s owner: derived before, or now if the seed is held; null if neither. The wallet's own is derived as it
|
|
55
59
|
* opens. */
|
|
56
60
|
export declare function owner(ctx: Ctx, code?: CodeId): Owner | null;
|
|
61
|
+
/** The key that signs where the refunds of the deposit address handed out with `code`'s burn address go. */
|
|
62
|
+
export declare function refundAccount(ctx: Ctx, code: CodeId): LocalAccount;
|
|
63
|
+
/** `refundAccount`'s address: derived before, or now if the seed is held; null if neither. */
|
|
64
|
+
export declare function refundSigner(ctx: Ctx, code: CodeId): Address | null;
|
|
57
65
|
export declare function chainCtx(ctx: Ctx, chainId: bigint): ChainCtx;
|
|
58
66
|
export declare function chainState(ctx: Ctx, chainId: bigint): ChainState;
|
|
59
67
|
/** `wc` on `chainId`, switched there first: a browser wallet is on one chain at a time. */
|
package/dist/context.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
// Everything an open wallet works with, shared by sync and the operations.
|
|
2
|
-
import { createWalletClient,
|
|
2
|
+
import { createWalletClient, publicActions, } from 'viem';
|
|
3
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
4
|
+
import { rpcTransport } from './chain.js';
|
|
3
5
|
import { core } from './core.js';
|
|
4
6
|
import { guard } from './errors.js';
|
|
7
|
+
import { refundKey } from './seed.js';
|
|
5
8
|
const keys = new WeakMap();
|
|
6
9
|
const idOf = (code) => (code ? `${code.chainId}:${code.tokenId}:${code.index}` : '');
|
|
7
10
|
/** The seed, which the wallet holds whenever it does what needs it. */
|
|
@@ -23,8 +26,9 @@ export function spendKey(ctx, code) {
|
|
|
23
26
|
key = (code ? core.codeSpendKey(seed, code.chainId, code.tokenId, code.index) : core.spendKey(seed));
|
|
24
27
|
bySeed.set(id, key);
|
|
25
28
|
}
|
|
29
|
+
const { authKeyHash, publicKey, nullifyingKey } = key;
|
|
26
30
|
if (!ctx.owners.has(id))
|
|
27
|
-
ctx.owners.set(id, {
|
|
31
|
+
ctx.owners.set(id, { authKeyHash, publicKey, nullifyingKey });
|
|
28
32
|
return key;
|
|
29
33
|
}
|
|
30
34
|
/** `spendKey`'s owner: derived before, or now if the seed is held; null if neither. The wallet's own is derived as it
|
|
@@ -32,6 +36,16 @@ export function spendKey(ctx, code) {
|
|
|
32
36
|
export function owner(ctx, code) {
|
|
33
37
|
return ctx.owners.get(idOf(code)) ?? (ctx.seed ? spendKey(ctx, code) : null);
|
|
34
38
|
}
|
|
39
|
+
/** The key that signs where the refunds of the deposit address handed out with `code`'s burn address go. */
|
|
40
|
+
export function refundAccount(ctx, code) {
|
|
41
|
+
const account = privateKeyToAccount(refundKey(seedOf(ctx), code.chainId, code.tokenId, code.index));
|
|
42
|
+
ctx.refundSigners.set(idOf(code), account.address);
|
|
43
|
+
return account;
|
|
44
|
+
}
|
|
45
|
+
/** `refundAccount`'s address: derived before, or now if the seed is held; null if neither. */
|
|
46
|
+
export function refundSigner(ctx, code) {
|
|
47
|
+
return ctx.refundSigners.get(idOf(code)) ?? (ctx.seed ? refundAccount(ctx, code).address : null);
|
|
48
|
+
}
|
|
35
49
|
export function chainCtx(ctx, chainId) {
|
|
36
50
|
const c = ctx.chains.find((c) => c.config.chainId === chainId);
|
|
37
51
|
if (!c)
|
|
@@ -55,7 +69,7 @@ export async function switched(wc, chainId) {
|
|
|
55
69
|
export async function walletOn(ctx, chainId) {
|
|
56
70
|
if (ctx.walletClient)
|
|
57
71
|
return switched(ctx.walletClient, chainId);
|
|
58
|
-
return createWalletClient({ account: ctx.account, transport:
|
|
72
|
+
return createWalletClient({ account: ctx.account, transport: rpcTransport(chainCtx(ctx, chainId).config.rpcUrl) });
|
|
59
73
|
}
|
|
60
74
|
/** Waits until the wallet's own node has a transaction mined on ours too: the wallet simulates the next one there, and
|
|
61
75
|
* where blocks are fast that node lags ours now and then, so the next one would show as reverting. A wallet that does
|
package/dist/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAG3E,OAAO,
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
|
package/dist/core.d.ts
CHANGED
|
@@ -9,8 +9,12 @@ export interface Burn {
|
|
|
9
9
|
}
|
|
10
10
|
/** The `index`-th burn address of `publicKey` on a chain and token, and its salt, from `burnKey`: the wallet's own burn
|
|
11
11
|
* key, or a point of sale's (`wallet_keys::derive_burn_address`). About 2^16 hashes, spread over the device's cores
|
|
12
|
-
* (Web Workers in a browser, worker threads in Node) so that the app stays responsive; `signal` stops the search.
|
|
13
|
-
|
|
12
|
+
* (Web Workers in a browser, worker threads in Node) so that the app stays responsive; `signal` stops the search. One
|
|
13
|
+
* that nobody waits for, made ahead, is `urgent: false`: it gives way to those someone waits for. */
|
|
14
|
+
export declare const burnAddress: (burnKey: Uint8Array, chainId: bigint, tokenId: number, index: number, publicKey: Hex, opts?: {
|
|
15
|
+
signal?: AbortSignal;
|
|
16
|
+
urgent?: boolean;
|
|
17
|
+
}) => Promise<Burn>;
|
|
14
18
|
/** A burn address of someone else's `publicKey` (one they published to be paid), with a random salt that has the proof
|
|
15
19
|
* of work: about 2^16 hashes too, searched the same way. Only who holds the salt finds it: the payer, and the owner once
|
|
16
20
|
* told (`planSend` with `burn`). */
|
|
@@ -36,9 +40,26 @@ export type BurnAnswer = {
|
|
|
36
40
|
} | {
|
|
37
41
|
error: string;
|
|
38
42
|
};
|
|
39
|
-
/**
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
/** What a block asks of the protocol code: `burnBlock`'s arguments, or `burnBlockFor`'s. */
|
|
44
|
+
export type BurnCall = {
|
|
45
|
+
burnKey: Uint8Array;
|
|
46
|
+
chainId: bigint;
|
|
47
|
+
tokenId: number;
|
|
48
|
+
index: number;
|
|
49
|
+
publicKey: Hex;
|
|
50
|
+
from: number;
|
|
51
|
+
to: number;
|
|
52
|
+
} | {
|
|
53
|
+
chainId: bigint;
|
|
54
|
+
publicKey: Hex;
|
|
55
|
+
start: Hex;
|
|
56
|
+
count: number;
|
|
57
|
+
};
|
|
58
|
+
/** A block's call. Its salts count up from a start: one the burn key derives, or for someone else's key a random one
|
|
59
|
+
* below 2^253, so that every salt is a field element. */
|
|
60
|
+
export declare function blockCall({ search: s, from, to }: BurnBlock): BurnCall;
|
|
61
|
+
/** The address a block holds, if any. */
|
|
62
|
+
export declare function runBlock(b: BurnBlock): Burn | null;
|
|
42
63
|
type Outcome = {
|
|
43
64
|
burn: Burn;
|
|
44
65
|
} | {
|
|
@@ -55,4 +76,13 @@ export declare class Search {
|
|
|
55
76
|
finish(block: number, burn: Burn | null): void;
|
|
56
77
|
fail(error: unknown): void;
|
|
57
78
|
}
|
|
79
|
+
/** Runs blocks somewhere other than this module's wasm: a server's native process, say. */
|
|
80
|
+
export interface BurnRunner {
|
|
81
|
+
/** How many blocks it runs at once. */
|
|
82
|
+
slots: number;
|
|
83
|
+
run(call: BurnCall): Promise<Burn | null>;
|
|
84
|
+
}
|
|
85
|
+
/** Runs every block from now on on `r`, or with null in this module's wasm again. The blocks the runner had are handed
|
|
86
|
+
* out again, and what it answers for them later is dropped. */
|
|
87
|
+
export declare function runBurnsOn(r: BurnRunner | null): void;
|
|
58
88
|
export {};
|