@zerc20/wallet-sdk 0.1.0 → 0.3.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/dist/burnWorker.js +6 -6
- package/dist/burnWorker.js.map +1 -1
- package/dist/chain.d.ts +19 -5
- package/dist/chain.js +17 -11
- package/dist/chain.js.map +1 -1
- package/dist/context.d.ts +23 -4
- package/dist/context.js +35 -6
- package/dist/context.js.map +1 -1
- package/dist/core.d.ts +32 -17
- package/dist/core.js +253 -70
- 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 +2 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/pos.js +2 -2
- package/dist/pos.js.map +1 -1
- package/dist/rageExit.js +3 -5
- package/dist/rageExit.js.map +1 -1
- package/dist/seed.d.ts +4 -0
- package/dist/seed.js +12 -1
- package/dist/seed.js.map +1 -1
- package/dist/services.d.ts +5 -5
- package/dist/services.js +10 -7
- package/dist/services.js.map +1 -1
- package/dist/spend.d.ts +1 -1
- package/dist/spend.js +5 -4
- package/dist/spend.js.map +1 -1
- package/dist/state.d.ts +14 -4
- package/dist/state.js +10 -7
- package/dist/state.js.map +1 -1
- package/dist/sync.d.ts +16 -3
- package/dist/sync.js +90 -25
- package/dist/sync.js.map +1 -1
- package/dist/wallet.d.ts +27 -13
- package/dist/wallet.js +125 -62
- package/dist/wallet.js.map +1 -1
- package/package.json +4 -3
- package/src/burnWorker.ts +9 -10
- package/src/chain.ts +35 -12
- package/src/context.ts +48 -8
- package/src/core.ts +279 -87
- package/src/errors.ts +2 -0
- package/src/index.ts +2 -2
- package/src/pos.ts +2 -2
- package/src/rageExit.ts +3 -4
- package/src/seed.ts +13 -1
- package/src/services.ts +18 -7
- package/src/spend.ts +5 -5
- package/src/state.ts +17 -7
- package/src/sync.ts +95 -24
- package/src/wallet.ts +159 -64
- package/wasm/zerc20_wallet_core.d.ts +16 -13
- package/wasm/zerc20_wallet_core.js +49 -42
- package/wasm/zerc20_wallet_core_bg.wasm +0 -0
- package/wasm/zerc20_wallet_core_bg.wasm.d.ts +3 -3
package/dist/burnWorker.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
import { initCore,
|
|
4
|
-
async function answer(
|
|
1
|
+
// Runs blocks of burn address searches off the main thread, one at a time: core.ts keeps a pool of these, Web Workers
|
|
2
|
+
// in a browser and worker threads in Node.
|
|
3
|
+
import { initCore, runBlock } from './core.js';
|
|
4
|
+
async function answer(b) {
|
|
5
5
|
try {
|
|
6
6
|
await initCore();
|
|
7
|
-
return { burn:
|
|
7
|
+
return { burn: runBlock(b) };
|
|
8
8
|
}
|
|
9
9
|
catch (e) {
|
|
10
10
|
return { error: e instanceof Error ? e.message : String(e) };
|
|
@@ -16,6 +16,6 @@ if (typeof self !== 'undefined') {
|
|
|
16
16
|
else {
|
|
17
17
|
// a variable, so that bundlers for the browser leave Node's module alone
|
|
18
18
|
const threads = 'node:worker_threads';
|
|
19
|
-
void import(/* @vite-ignore */ threads).then(
|
|
19
|
+
void import(/* @vite-ignore */ threads).then(({ parentPort }) => parentPort.on('message', (b) => void answer(b).then((a) => parentPort.postMessage(a))));
|
|
20
20
|
}
|
|
21
21
|
//# sourceMappingURL=burnWorker.js.map
|
package/dist/burnWorker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"burnWorker.js","sourceRoot":"","sources":["../src/burnWorker.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"burnWorker.js","sourceRoot":"","sources":["../src/burnWorker.ts"],"names":[],"mappings":"AAAA,sHAAsH;AACtH,2CAA2C;AAE3C,OAAO,EAAmC,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEhF,KAAK,UAAU,MAAM,CAAC,CAAY;IAChC,IAAI,CAAC;QACH,MAAM,QAAQ,EAAE,CAAC;QACjB,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,KAAK,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,IAAI,OAAO,IAAI,KAAK,WAAW,EAAE,CAAC;IAChC,IAAI,CAAC,SAAS,GAAG,KAAK,EAAE,EAAE,IAAI,EAA2B,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AAChG,CAAC;KAAM,CAAC;IACN,yEAAyE;IACzE,MAAM,OAAO,GAAG,qBAAqB,CAAC;IAEtC,KAAK,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,EAAwB,EAAE,EAAE,CACpF,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CACvF,CAAC;AACJ,CAAC"}
|
package/dist/chain.d.ts
CHANGED
|
@@ -288,11 +288,25 @@ export declare const depositFactoryAbi: readonly [{
|
|
|
288
288
|
}, {
|
|
289
289
|
readonly type: "uint256";
|
|
290
290
|
readonly name: "fee";
|
|
291
|
+
}, {
|
|
292
|
+
readonly type: "address";
|
|
293
|
+
readonly name: "referrer";
|
|
294
|
+
}, {
|
|
295
|
+
readonly type: "uint16";
|
|
296
|
+
readonly name: "referralBps";
|
|
291
297
|
}];
|
|
292
298
|
readonly outputs: readonly [{
|
|
293
299
|
readonly type: "address";
|
|
294
300
|
}];
|
|
295
301
|
}];
|
|
302
|
+
/** The factory's `MAX_REFERRAL_BPS`: the most of a deposit, after the relayer's fee, that a referrer can take. */
|
|
303
|
+
export declare const MAX_REFERRAL_BPS = 300;
|
|
304
|
+
/** An app that hands out deposit addresses and takes `bps` of each payment to them, of what is left after the relayer's
|
|
305
|
+
* fee. `address` is paid, and also names the app on chain. */
|
|
306
|
+
export interface Referrer {
|
|
307
|
+
address: Address;
|
|
308
|
+
bps: number;
|
|
309
|
+
}
|
|
296
310
|
export declare const depositAddressAbi: readonly [{
|
|
297
311
|
readonly name: "refund";
|
|
298
312
|
readonly type: "function";
|
|
@@ -327,12 +341,12 @@ export declare class Chain {
|
|
|
327
341
|
get chainId(): bigint;
|
|
328
342
|
ledger(): Promise<Address>;
|
|
329
343
|
/** The deposit address the factory deploys for `token`, `burnAddress` and `refundAddress`, whose flush pays `fee`
|
|
330
|
-
* to `feeRecipient`. */
|
|
331
|
-
predictDepositAddress(token: Address, burnAddress: Hex, refundAddress: Address, feeRecipient: Address, fee: bigint): Promise<Address>;
|
|
344
|
+
* to `feeRecipient` and `referralBps` of the rest to `referrer`. */
|
|
345
|
+
predictDepositAddress(token: Address, burnAddress: Hex, refundAddress: Address, feeRecipient: Address, fee: bigint, referrer: Address, referralBps: number): Promise<Address>;
|
|
332
346
|
/** The refund address of `address` if it is a deployed deposit address for `token` and `burnAddress`, whatever its
|
|
333
|
-
* refund address and
|
|
334
|
-
* burnAddress, refundAddress, feeRecipient, fee)`; the factory's address
|
|
335
|
-
* like one does not pass. */
|
|
347
|
+
* refund address, fee and referral; null if it is not one. A clone's code ends with its immutable args,
|
|
348
|
+
* `abi.encode(token, burnAddress, refundAddress, feeRecipient, fee, referrer, referralBps)`; the factory's address
|
|
349
|
+
* for them confirms it, so code made to look like one does not pass. */
|
|
336
350
|
depositAddressRefund(address: Address, token: Address, burnAddress: Hex): Promise<Address | null>;
|
|
337
351
|
/** Whether the ledger accepts `root` as the tree at `size` leaves. */
|
|
338
352
|
provedRoot(size: number, root: Hex): Promise<boolean>;
|
package/dist/chain.js
CHANGED
|
@@ -35,8 +35,10 @@ 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) view returns (address)',
|
|
38
|
+
'function predict(address token, address burnAddress, address refundAddress, address feeRecipient, uint256 fee, address referrer, uint16 referralBps) view returns (address)',
|
|
39
39
|
]);
|
|
40
|
+
/** The factory's `MAX_REFERRAL_BPS`: the most of a deposit, after the relayer's fee, that a referrer can take. */
|
|
41
|
+
export const MAX_REFERRAL_BPS = 300;
|
|
40
42
|
export const depositAddressAbi = parseAbi(['function refund(address asset)']);
|
|
41
43
|
/** The native asset's stand-in for `underlyingAsset`. */
|
|
42
44
|
export const NATIVE = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';
|
|
@@ -65,27 +67,31 @@ export class Chain {
|
|
|
65
67
|
return this.#ledger;
|
|
66
68
|
}
|
|
67
69
|
/** The deposit address the factory deploys for `token`, `burnAddress` and `refundAddress`, whose flush pays `fee`
|
|
68
|
-
* to `feeRecipient`. */
|
|
69
|
-
predictDepositAddress(token, burnAddress, refundAddress, feeRecipient, fee) {
|
|
70
|
+
* to `feeRecipient` and `referralBps` of the rest to `referrer`. */
|
|
71
|
+
predictDepositAddress(token, burnAddress, refundAddress, feeRecipient, fee, referrer, referralBps) {
|
|
70
72
|
return this.client.readContract({
|
|
71
73
|
address: this.config.depositAddressFactory,
|
|
72
74
|
abi: depositFactoryAbi,
|
|
73
75
|
functionName: 'predict',
|
|
74
|
-
args: [token, burnAddress, refundAddress, feeRecipient, fee],
|
|
76
|
+
args: [token, burnAddress, refundAddress, feeRecipient, fee, referrer, referralBps],
|
|
75
77
|
});
|
|
76
78
|
}
|
|
77
79
|
/** The refund address of `address` if it is a deployed deposit address for `token` and `burnAddress`, whatever its
|
|
78
|
-
* refund address and
|
|
79
|
-
* burnAddress, refundAddress, feeRecipient, fee)`; the factory's address
|
|
80
|
-
* like one does not pass. */
|
|
80
|
+
* refund address, fee and referral; null if it is not one. A clone's code ends with its immutable args,
|
|
81
|
+
* `abi.encode(token, burnAddress, refundAddress, feeRecipient, fee, referrer, referralBps)`; the factory's address
|
|
82
|
+
* for them confirms it, so code made to look like one does not pass. */
|
|
81
83
|
async depositAddressRefund(address, token, burnAddress) {
|
|
82
84
|
const code = await this.client.getCode({ address });
|
|
83
|
-
if (!code || size(code) <
|
|
85
|
+
if (!code || size(code) < 224)
|
|
84
86
|
return null;
|
|
85
|
-
|
|
87
|
+
// 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([{ type: 'address' }, { type: 'address' }, { type: 'uint256' }, { type: 'address' }, { type: 'uint256' }], slice(code, size(code) - 160));
|
|
89
|
+
// predict would revert
|
|
86
90
|
if (refundAddress === zeroAddress || feeRecipient === zeroAddress)
|
|
87
|
-
return null;
|
|
88
|
-
|
|
91
|
+
return null;
|
|
92
|
+
if (referralBps > MAX_REFERRAL_BPS || (referrer === zeroAddress && referralBps !== 0n))
|
|
93
|
+
return null;
|
|
94
|
+
const expected = await this.predictDepositAddress(token, burnAddress, refundAddress, feeRecipient, fee, referrer, Number(referralBps));
|
|
89
95
|
return expected.toLowerCase() === address.toLowerCase() ? refundAddress : null;
|
|
90
96
|
}
|
|
91
97
|
/** Whether the ledger accepts `root` as the tree at `size` leaves. */
|
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":"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,6KAA6K;CAC9K,CAAC,CAAC;AAEH,kHAAkH;AAClH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAC;AASpC,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC;AAE9E,yDAAyD;AACzD,MAAM,CAAC,MAAM,MAAM,GAAY,4CAA4C,CAAC;AAE5E;uDACuD;AACvD,MAAM,CAAC,MAAM,aAAa,GACxB,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAC/C,8EAA8E,CAAC;AAcjF,MAAM,OAAO,KAAK;IAKK;IAJZ,MAAM,CAAe;IAC9B,OAAO,CAAoB;IAC3B,OAAO,CAAW;IAElB,YAAqB,MAAmB;QAAnB,WAAM,GAAN,MAAM,CAAa;QACtC,IAAI,CAAC,MAAM,GAAG,kBAAkB,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;IAC7B,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;YACxC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC7B,GAAG,EAAE,WAAW;YAChB,YAAY,EAAE,QAAQ;SACvB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;wEACoE;IACpE,qBAAqB,CACnB,KAAc,EACd,WAAgB,EAChB,aAAsB,EACtB,YAAqB,EACrB,GAAW,EACX,QAAiB,EACjB,WAAmB;QAEnB,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;YAC9B,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,qBAAqB;YAC1C,GAAG,EAAE,iBAAiB;YACtB,YAAY,EAAE,SAAS;YACvB,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,EAAE,WAAW,CAAC;SACpF,CAAC,CAAC;IACL,CAAC;IAED;;;4EAGwE;IACxE,KAAK,CAAC,oBAAoB,CAAC,OAAgB,EAAE,KAAc,EAAE,WAAgB;QAC3E,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG;YAAE,OAAO,IAAI,CAAC;QAC3C,oGAAoG;QACpG,MAAM,CAAC,aAAa,EAAE,YAAY,EAAE,GAAG,EAAE,QAAQ,EAAE,WAAW,CAAC,GAAG,mBAAmB,CACnF,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EACzG,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAC9B,CAAC;QACF,uBAAuB;QACvB,IAAI,aAAa,KAAK,WAAW,IAAI,YAAY,KAAK,WAAW;YAAE,OAAO,IAAI,CAAC;QAC/E,IAAI,WAAW,GAAG,gBAAgB,IAAI,CAAC,QAAQ,KAAK,WAAW,IAAI,WAAW,KAAK,EAAE,CAAC;YAAE,OAAO,IAAI,CAAC;QACpG,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAC/C,KAAK,EACL,WAAW,EACX,aAAa,EACb,YAAY,EACZ,GAAG,EACH,QAAQ,EACR,MAAM,CAAC,WAAW,CAAC,CACpB,CAAC;QACF,OAAO,QAAQ,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;IACjF,CAAC;IAED,sEAAsE;IACtE,KAAK,CAAC,UAAU,CAAC,IAAY,EAAE,IAAS;QACtC,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;YAC9B,OAAO,EAAE,MAAM,IAAI,CAAC,MAAM,EAAE;YAC5B,GAAG,EAAE,SAAS;YACd,YAAY,EAAE,aAAa;YAC3B,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;SACnC,CAAC,CAAC;IACL,CAAC;IAED,2GAA2G;IAC3G,KAAK,CAAC,KAAK;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3G,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;YAC1C,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC7B,GAAG,EAAE,WAAW;YAChB,YAAY,EAAE,eAAe;SAC9B,CAAC,CAAC;QACH,OAAO,WAAW,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,WAAW,CAAC,OAAe,EAAE,MAAc;QACzC,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;YAC9B,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC7B,GAAG,EAAE,WAAW;YAChB,YAAY,EAAE,aAAa;YAC3B,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;SACxB,CAAC,CAAC;IACL,CAAC;IAED,oFAAoF;IACpF,KAAK,CAAC,MAAM;QACV,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;YAC7C,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC7B,GAAG,EAAE,WAAW;YAChB,YAAY,EAAE,SAAS;SACxB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC,CAAC;QAChH,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;YAC1D,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;YACrC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;gBAC7C,OAAO,EAAE,OAAO;gBAChB,GAAG,EAAE,UAAU;gBACf,YAAY,EAAE,WAAW;gBACzB,IAAI,EAAE,CAAC,OAAO,CAAC;aAChB,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,CAAsD,YAAe,EAAE,EAAE,CACpF,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC;YACrE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACvD,IAAI,CAAC,QAAQ,CAAC;gBACd,IAAI,CAAC,UAAU,CAAC;gBAChB,IAAI,CAAC,iBAAiB,CAAC;aACxB,CAAC,CAAC;YACH,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;QACnF,CAAC,CAAC,CACH,CAAC;QACF,IAAI,CAAC,OAAO,GAAG,CAAC,GAAG,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CACF"}
|
package/dist/context.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CanisterClient, ViewKey } from '@zerc20/storage-sdk';
|
|
2
|
-
import { type Hex, type WalletClient } from 'viem';
|
|
2
|
+
import { type Account, type Hex, type WalletClient } from 'viem';
|
|
3
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';
|
|
@@ -18,11 +18,20 @@ export interface SpendKey {
|
|
|
18
18
|
publicKey: Hex;
|
|
19
19
|
nullifyingKey: Hex;
|
|
20
20
|
}
|
|
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'>;
|
|
21
24
|
export interface Ctx {
|
|
22
25
|
network: Network;
|
|
23
|
-
|
|
26
|
+
/** The root of every key. Opened with a function for it, held only while something needs it; otherwise always. */
|
|
27
|
+
seed: Uint8Array | null;
|
|
28
|
+
/** The owners derived while the seed was held, by key: the wallet's own (`''`) and each receive code's. */
|
|
29
|
+
owners: Map<string, Owner>;
|
|
24
30
|
address: Hex;
|
|
25
|
-
|
|
31
|
+
/** The account that holds the public funds, and signs for them. */
|
|
32
|
+
account: Account;
|
|
33
|
+
/** The user's wallet, when it is what signs and sends rather than an account of the app's own (`walletOn`). */
|
|
34
|
+
walletClient: WalletClient | null;
|
|
26
35
|
storage: CanisterClient;
|
|
27
36
|
view: ViewKey;
|
|
28
37
|
chains: ChainCtx[];
|
|
@@ -37,11 +46,21 @@ export interface CodeId {
|
|
|
37
46
|
tokenId: number;
|
|
38
47
|
index: number;
|
|
39
48
|
}
|
|
49
|
+
/** The seed, which the wallet holds whenever it does what needs it. */
|
|
50
|
+
export declare function seedOf(ctx: Ctx): Uint8Array;
|
|
40
51
|
/** The key that owns this seed's notes and deposits on every chain and token, or with `code`, the notes paid to that
|
|
41
|
-
* receive code. */
|
|
52
|
+
* receive code. Its owner is kept for when the seed is not held. */
|
|
42
53
|
export declare function spendKey(ctx: Ctx, code?: CodeId): SpendKey;
|
|
54
|
+
/** `spendKey`'s owner: derived before, or now if the seed is held; null if neither. The wallet's own is derived as it
|
|
55
|
+
* opens. */
|
|
56
|
+
export declare function owner(ctx: Ctx, code?: CodeId): Owner | null;
|
|
43
57
|
export declare function chainCtx(ctx: Ctx, chainId: bigint): ChainCtx;
|
|
44
58
|
export declare function chainState(ctx: Ctx, chainId: bigint): ChainState;
|
|
59
|
+
/** `wc` on `chainId`, switched there first: a browser wallet is on one chain at a time. */
|
|
60
|
+
export declare function switched(wc: WalletClient, chainId: bigint): Promise<WalletClient>;
|
|
61
|
+
/** The client that sends the account's transactions on `chainId`: the user's wallet, switched to the chain, or the
|
|
62
|
+
* app's own account, through the chain's RPC. */
|
|
63
|
+
export declare function walletOn(ctx: Ctx, chainId: bigint): Promise<WalletClient>;
|
|
45
64
|
/** Waits until the wallet's own node has a transaction mined on ours too: the wallet simulates the next one there, and
|
|
46
65
|
* where blocks are fast that node lags ours now and then, so the next one would show as reverting. A wallet that does
|
|
47
66
|
* not answer is not waited on. */
|
package/dist/context.js
CHANGED
|
@@ -1,21 +1,37 @@
|
|
|
1
1
|
// Everything an open wallet works with, shared by sync and the operations.
|
|
2
|
-
import { publicActions } from 'viem';
|
|
2
|
+
import { createWalletClient, http, publicActions } from 'viem';
|
|
3
3
|
import { core } from './core.js';
|
|
4
|
+
import { guard } from './errors.js';
|
|
4
5
|
const keys = new WeakMap();
|
|
6
|
+
const idOf = (code) => (code ? `${code.chainId}:${code.tokenId}:${code.index}` : '');
|
|
7
|
+
/** The seed, which the wallet holds whenever it does what needs it. */
|
|
8
|
+
export function seedOf(ctx) {
|
|
9
|
+
if (!ctx.seed)
|
|
10
|
+
throw new Error('the wallet does not hold its seed now');
|
|
11
|
+
return ctx.seed;
|
|
12
|
+
}
|
|
5
13
|
/** The key that owns this seed's notes and deposits on every chain and token, or with `code`, the notes paid to that
|
|
6
|
-
* receive code. */
|
|
14
|
+
* receive code. Its owner is kept for when the seed is not held. */
|
|
7
15
|
export function spendKey(ctx, code) {
|
|
8
|
-
|
|
16
|
+
const seed = seedOf(ctx);
|
|
17
|
+
let bySeed = keys.get(seed);
|
|
9
18
|
if (!bySeed)
|
|
10
|
-
keys.set(
|
|
11
|
-
const id = code
|
|
19
|
+
keys.set(seed, (bySeed = new Map()));
|
|
20
|
+
const id = idOf(code);
|
|
12
21
|
let key = bySeed.get(id);
|
|
13
22
|
if (!key) {
|
|
14
|
-
key = (code ? core.
|
|
23
|
+
key = (code ? core.codeSpendKey(seed, code.chainId, code.tokenId, code.index) : core.spendKey(seed));
|
|
15
24
|
bySeed.set(id, key);
|
|
16
25
|
}
|
|
26
|
+
if (!ctx.owners.has(id))
|
|
27
|
+
ctx.owners.set(id, { publicKey: key.publicKey, nullifyingKey: key.nullifyingKey });
|
|
17
28
|
return key;
|
|
18
29
|
}
|
|
30
|
+
/** `spendKey`'s owner: derived before, or now if the seed is held; null if neither. The wallet's own is derived as it
|
|
31
|
+
* opens. */
|
|
32
|
+
export function owner(ctx, code) {
|
|
33
|
+
return ctx.owners.get(idOf(code)) ?? (ctx.seed ? spendKey(ctx, code) : null);
|
|
34
|
+
}
|
|
19
35
|
export function chainCtx(ctx, chainId) {
|
|
20
36
|
const c = ctx.chains.find((c) => c.config.chainId === chainId);
|
|
21
37
|
if (!c)
|
|
@@ -28,6 +44,19 @@ export function chainState(ctx, chainId) {
|
|
|
28
44
|
ctx.state.chains.push((s = { chainId, samples: [], burnNext: {} }));
|
|
29
45
|
return s;
|
|
30
46
|
}
|
|
47
|
+
/** `wc` on `chainId`, switched there first: a browser wallet is on one chain at a time. */
|
|
48
|
+
export async function switched(wc, chainId) {
|
|
49
|
+
if ((await wc.getChainId()) !== Number(chainId))
|
|
50
|
+
await guard(wc.switchChain({ id: Number(chainId) }));
|
|
51
|
+
return wc;
|
|
52
|
+
}
|
|
53
|
+
/** The client that sends the account's transactions on `chainId`: the user's wallet, switched to the chain, or the
|
|
54
|
+
* app's own account, through the chain's RPC. */
|
|
55
|
+
export async function walletOn(ctx, chainId) {
|
|
56
|
+
if (ctx.walletClient)
|
|
57
|
+
return switched(ctx.walletClient, chainId);
|
|
58
|
+
return createWalletClient({ account: ctx.account, transport: http(chainCtx(ctx, chainId).config.rpcUrl) });
|
|
59
|
+
}
|
|
31
60
|
/** Waits until the wallet's own node has a transaction mined on ours too: the wallet simulates the next one there, and
|
|
32
61
|
* where blocks are fast that node lags ours now and then, so the next one would show as reverting. A wallet that does
|
|
33
62
|
* not answer is not waited on. */
|
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
|
@@ -7,37 +7,52 @@ export interface Burn {
|
|
|
7
7
|
salt: Hex;
|
|
8
8
|
address: Address;
|
|
9
9
|
}
|
|
10
|
-
/**
|
|
11
|
-
*
|
|
12
|
-
* responsive; `signal` stops the search. */
|
|
13
|
-
export declare const burnAddress: (
|
|
14
|
-
/** The `k`-th burn address a point of sale holding `laneKey` makes for its owner's `publicKey` on a chain and token
|
|
15
|
-
* (`keys::pos_burn`), with its salt: about 2^16 hashes too, searched the same way. */
|
|
16
|
-
export declare const posBurnAddress: (laneKey: Uint8Array, chainId: bigint, tokenId: number, k: number, publicKey: Hex, signal?: AbortSignal) => Promise<Burn>;
|
|
10
|
+
/** The `index`-th burn address of `publicKey` on a chain and token, and its salt, from `burnKey`: the wallet's own burn
|
|
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
|
+
export declare const burnAddress: (burnKey: Uint8Array, chainId: bigint, tokenId: number, index: number, publicKey: Hex, signal?: AbortSignal) => Promise<Burn>;
|
|
17
14
|
/** A burn address of someone else's `publicKey` (one they published to be paid), with a random salt that has the proof
|
|
18
15
|
* of work: about 2^16 hashes too, searched the same way. Only who holds the salt finds it: the payer, and the owner once
|
|
19
16
|
* told (`planSend` with `burn`). */
|
|
20
17
|
export declare const burnAddressFor: (chainId: bigint, publicKey: Hex, signal?: AbortSignal) => Promise<Burn>;
|
|
21
18
|
export type BurnSearch = {
|
|
22
|
-
|
|
19
|
+
burnKey: Uint8Array;
|
|
23
20
|
chainId: bigint;
|
|
24
21
|
tokenId: number;
|
|
25
22
|
index: number;
|
|
26
|
-
} | {
|
|
27
|
-
laneKey: Uint8Array;
|
|
28
|
-
chainId: bigint;
|
|
29
|
-
tokenId: number;
|
|
30
|
-
k: number;
|
|
31
23
|
publicKey: Hex;
|
|
32
24
|
} | {
|
|
33
25
|
chainId: bigint;
|
|
34
26
|
publicKey: Hex;
|
|
35
27
|
};
|
|
36
|
-
/** A
|
|
37
|
-
|
|
38
|
-
|
|
28
|
+
/** A block of a search: its salt counters `from..=to`, or as many random salts for someone else's key. */
|
|
29
|
+
export interface BurnBlock {
|
|
30
|
+
search: BurnSearch;
|
|
31
|
+
from: number;
|
|
32
|
+
to: number;
|
|
33
|
+
}
|
|
39
34
|
export type BurnAnswer = {
|
|
40
|
-
burn: Burn;
|
|
35
|
+
burn: Burn | null;
|
|
41
36
|
} | {
|
|
42
37
|
error: string;
|
|
43
38
|
};
|
|
39
|
+
/** The address a block holds, if any. Its salts count up from a start: one the burn key derives, or for someone else's
|
|
40
|
+
* key a random one below 2^253, so that every salt is a field element. */
|
|
41
|
+
export declare function runBlock({ search: s, from, to }: BurnBlock): Burn | null;
|
|
42
|
+
type Outcome = {
|
|
43
|
+
burn: Burn;
|
|
44
|
+
} | {
|
|
45
|
+
error: unknown;
|
|
46
|
+
};
|
|
47
|
+
/** A search in progress, in blocks `0, 1, …` of `BLOCK` counters. From a burn key, the address is the first block's
|
|
48
|
+
* hit, so that every device derives the same one; for someone else's key, it is the first found. */
|
|
49
|
+
export declare class Search {
|
|
50
|
+
#private;
|
|
51
|
+
readonly s: BurnSearch;
|
|
52
|
+
constructor(s: BurnSearch, settle: (r: Outcome) => void);
|
|
53
|
+
take(): number | undefined;
|
|
54
|
+
drop(block: number): void;
|
|
55
|
+
finish(block: number, burn: Burn | null): void;
|
|
56
|
+
fail(error: unknown): void;
|
|
57
|
+
}
|
|
58
|
+
export {};
|