@miden-sdk/miden-wallet-adapter-base 0.15.2 → 0.16.0-rc.5
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/LICENSE +21 -0
- package/__tests__/adapter.test.ts +18 -18
- package/__tests__/errors.test.ts +40 -40
- package/__tests__/helpers.test.ts +15 -15
- package/__tests__/signer.test.ts +8 -8
- package/__tests__/transaction.test.ts +65 -65
- package/adapter.ts +15 -15
- package/dist/__tests__/adapter.test.js +18 -18
- package/dist/__tests__/errors.test.js +40 -40
- package/dist/__tests__/helpers.test.js +15 -15
- package/dist/__tests__/signer.test.js +7 -7
- package/dist/__tests__/transaction.test.js +51 -51
- package/dist/adapter.d.ts +4 -4
- package/dist/adapter.js +8 -8
- package/dist/errors.js +22 -22
- package/dist/errors.js.map +1 -1
- package/dist/helpers.js +7 -7
- package/dist/index.d.ts +6 -6
- package/dist/index.js +6 -6
- package/dist/signer.d.ts +5 -5
- package/dist/signer.js +1 -1
- package/dist/signer.js.map +1 -1
- package/dist/transaction.d.ts +2 -2
- package/dist/transaction.js +1 -1
- package/dist/types.d.ts +6 -6
- package/dist/vitest.config.js +2 -2
- package/docs/README.md +0 -4
- package/docs/classes/BaseMessageSignerWalletAdapter.md +0 -34
- package/docs/enumerations/WalletAdapterNetwork.md +0 -6
- package/docs/interfaces/MessageSignerWalletAdapterProps.md +0 -26
- package/errors.ts +28 -28
- package/helpers.ts +8 -8
- package/index.ts +6 -6
- package/package.json +19 -10
- package/signer.ts +20 -11
- package/transaction.ts +6 -6
- package/types.ts +16 -16
- package/vitest.config.ts +2 -2
- package/docs/interfaces/CreateAccountParams.md +0 -25
- package/docs/interfaces/GuardianInfo.md +0 -31
- package/docs/type-aliases/CreateAccountStorageMode.md +0 -9
- package/docs/type-aliases/CreateAccountType.md +0 -9
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Miden
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
2
|
import {
|
|
3
3
|
WalletReadyState,
|
|
4
4
|
BaseWalletAdapter,
|
|
5
5
|
scopePollingDetectionStrategy,
|
|
6
|
-
} from
|
|
6
|
+
} from "../adapter";
|
|
7
7
|
|
|
8
|
-
describe(
|
|
9
|
-
it(
|
|
10
|
-
expect(WalletReadyState.Installed).toBe(
|
|
11
|
-
expect(WalletReadyState.NotDetected).toBe(
|
|
12
|
-
expect(WalletReadyState.Loadable).toBe(
|
|
13
|
-
expect(WalletReadyState.Unsupported).toBe(
|
|
8
|
+
describe("WalletReadyState enum", () => {
|
|
9
|
+
it("has correct values", () => {
|
|
10
|
+
expect(WalletReadyState.Installed).toBe("Installed");
|
|
11
|
+
expect(WalletReadyState.NotDetected).toBe("NotDetected");
|
|
12
|
+
expect(WalletReadyState.Loadable).toBe("Loadable");
|
|
13
|
+
expect(WalletReadyState.Unsupported).toBe("Unsupported");
|
|
14
14
|
});
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
describe(
|
|
17
|
+
describe("BaseWalletAdapter", () => {
|
|
18
18
|
// Concrete subclass for testing
|
|
19
19
|
class TestAdapter extends BaseWalletAdapter {
|
|
20
|
-
name =
|
|
21
|
-
url =
|
|
22
|
-
icon =
|
|
20
|
+
name = "Test" as any;
|
|
21
|
+
url = "https://test.com";
|
|
22
|
+
icon = "icon";
|
|
23
23
|
readyState = WalletReadyState.Installed;
|
|
24
24
|
address: string | null = null;
|
|
25
25
|
publicKey: Uint8Array | null = null;
|
|
@@ -30,19 +30,19 @@ describe('BaseWalletAdapter', () => {
|
|
|
30
30
|
async disconnect() {}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
it(
|
|
33
|
+
it("connected returns true when address is set", () => {
|
|
34
34
|
const adapter = new TestAdapter();
|
|
35
|
-
adapter.address =
|
|
35
|
+
adapter.address = "0xabc";
|
|
36
36
|
expect(adapter.connected).toBe(true);
|
|
37
37
|
});
|
|
38
38
|
|
|
39
|
-
it(
|
|
39
|
+
it("connected returns false when address is null", () => {
|
|
40
40
|
const adapter = new TestAdapter();
|
|
41
41
|
expect(adapter.connected).toBe(false);
|
|
42
42
|
});
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
describe(
|
|
45
|
+
describe("scopePollingDetectionStrategy", () => {
|
|
46
46
|
beforeEach(() => {
|
|
47
47
|
vi.useFakeTimers();
|
|
48
48
|
});
|
|
@@ -51,13 +51,13 @@ describe('scopePollingDetectionStrategy', () => {
|
|
|
51
51
|
vi.useRealTimers();
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
-
it(
|
|
54
|
+
it("calls detect immediately and cleans up on detection", () => {
|
|
55
55
|
const detect = vi.fn().mockReturnValue(true);
|
|
56
56
|
scopePollingDetectionStrategy(detect);
|
|
57
57
|
expect(detect).toHaveBeenCalled();
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
-
it(
|
|
60
|
+
it("sets up polling interval when not immediately detected", () => {
|
|
61
61
|
let callCount = 0;
|
|
62
62
|
const detect = vi.fn(() => {
|
|
63
63
|
callCount++;
|
package/__tests__/errors.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, it, expect } from
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
2
|
import {
|
|
3
3
|
WalletError,
|
|
4
4
|
WalletNotReadyError,
|
|
@@ -23,77 +23,77 @@ import {
|
|
|
23
23
|
WalletDecryptionError,
|
|
24
24
|
WalletRecordsError,
|
|
25
25
|
WalletTransactionError,
|
|
26
|
-
} from
|
|
26
|
+
} from "../errors";
|
|
27
27
|
|
|
28
28
|
const errorClasses = [
|
|
29
|
-
{ Class: WalletNotReadyError, name:
|
|
30
|
-
{ Class: WalletLoadError, name:
|
|
31
|
-
{ Class: WalletConfigError, name:
|
|
32
|
-
{ Class: WalletConnectionError, name:
|
|
33
|
-
{ Class: WalletNotSelectedError, name:
|
|
34
|
-
{ Class: WalletDisconnectedError, name:
|
|
35
|
-
{ Class: WalletDisconnectionError, name:
|
|
36
|
-
{ Class: WalletAccountError, name:
|
|
37
|
-
{ Class: WalletAddressError, name:
|
|
38
|
-
{ Class: WalletKeypairError, name:
|
|
39
|
-
{ Class: WalletNotConnectedError, name:
|
|
40
|
-
{ Class: WalletSendTransactionError, name:
|
|
41
|
-
{ Class: WalletSignMessageError, name:
|
|
42
|
-
{ Class: WalletSignTransactionError, name:
|
|
43
|
-
{ Class: WalletTimeoutError, name:
|
|
44
|
-
{ Class: WalletWindowBlockedError, name:
|
|
45
|
-
{ Class: WalletWindowClosedError, name:
|
|
29
|
+
{ Class: WalletNotReadyError, name: "WalletNotReadyError" },
|
|
30
|
+
{ Class: WalletLoadError, name: "WalletLoadError" },
|
|
31
|
+
{ Class: WalletConfigError, name: "WalletConfigError" },
|
|
32
|
+
{ Class: WalletConnectionError, name: "WalletConnectionError" },
|
|
33
|
+
{ Class: WalletNotSelectedError, name: "WalletNotSelectedError" },
|
|
34
|
+
{ Class: WalletDisconnectedError, name: "WalletDisconnectedError" },
|
|
35
|
+
{ Class: WalletDisconnectionError, name: "WalletDisconnectionError" },
|
|
36
|
+
{ Class: WalletAccountError, name: "WalletAccountError" },
|
|
37
|
+
{ Class: WalletAddressError, name: "WalletAddressError" },
|
|
38
|
+
{ Class: WalletKeypairError, name: "WalletKeypairError" },
|
|
39
|
+
{ Class: WalletNotConnectedError, name: "WalletNotConnectedError" },
|
|
40
|
+
{ Class: WalletSendTransactionError, name: "WalletSendTransactionError" },
|
|
41
|
+
{ Class: WalletSignMessageError, name: "WalletSignMessageError" },
|
|
42
|
+
{ Class: WalletSignTransactionError, name: "WalletSignTransactionError" },
|
|
43
|
+
{ Class: WalletTimeoutError, name: "WalletTimeoutError" },
|
|
44
|
+
{ Class: WalletWindowBlockedError, name: "WalletWindowBlockedError" },
|
|
45
|
+
{ Class: WalletWindowClosedError, name: "WalletWindowClosedError" },
|
|
46
46
|
{
|
|
47
47
|
Class: WalletDecryptionNotAllowedError,
|
|
48
|
-
name:
|
|
48
|
+
name: "WalletDecryptionNotAllowedError",
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
51
|
Class: WalletPrivateDataPermissionError,
|
|
52
|
-
name:
|
|
52
|
+
name: "WalletPrivateDataPermissionError",
|
|
53
53
|
},
|
|
54
|
-
{ Class: WalletDecryptionError, name:
|
|
55
|
-
{ Class: WalletRecordsError, name:
|
|
56
|
-
{ Class: WalletTransactionError, name:
|
|
54
|
+
{ Class: WalletDecryptionError, name: "WalletDecryptionError" },
|
|
55
|
+
{ Class: WalletRecordsError, name: "WalletRecordsError" },
|
|
56
|
+
{ Class: WalletTransactionError, name: "WalletTransactionError" },
|
|
57
57
|
] as const;
|
|
58
58
|
|
|
59
|
-
describe(
|
|
60
|
-
it(
|
|
61
|
-
const err = new WalletError(
|
|
59
|
+
describe("WalletError", () => {
|
|
60
|
+
it("extends Error", () => {
|
|
61
|
+
const err = new WalletError("test message");
|
|
62
62
|
expect(err).toBeInstanceOf(Error);
|
|
63
63
|
expect(err).toBeInstanceOf(WalletError);
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
-
it(
|
|
67
|
-
const err = new WalletError(
|
|
68
|
-
expect(err.message).toBe(
|
|
66
|
+
it("sets message property", () => {
|
|
67
|
+
const err = new WalletError("my message");
|
|
68
|
+
expect(err.message).toBe("my message");
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
-
it(
|
|
72
|
-
const inner = new Error(
|
|
73
|
-
const err = new WalletError(
|
|
71
|
+
it("stores inner error", () => {
|
|
72
|
+
const inner = new Error("inner");
|
|
73
|
+
const err = new WalletError("outer", inner);
|
|
74
74
|
expect(err.error).toBe(inner);
|
|
75
75
|
});
|
|
76
76
|
});
|
|
77
77
|
|
|
78
|
-
describe(
|
|
78
|
+
describe("error subclasses", () => {
|
|
79
79
|
for (const { Class, name } of errorClasses) {
|
|
80
80
|
describe(name, () => {
|
|
81
|
-
it(
|
|
81
|
+
it("extends WalletError and Error", () => {
|
|
82
82
|
const err = new Class();
|
|
83
83
|
expect(err).toBeInstanceOf(WalletError);
|
|
84
84
|
expect(err).toBeInstanceOf(Error);
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
-
it(
|
|
87
|
+
it("has correct name property", () => {
|
|
88
88
|
const err = new Class();
|
|
89
89
|
expect(err.name).toBe(name);
|
|
90
90
|
});
|
|
91
91
|
|
|
92
|
-
it(
|
|
93
|
-
const inner = new Error(
|
|
94
|
-
const err = new Class(
|
|
92
|
+
it("stores inner error", () => {
|
|
93
|
+
const inner = new Error("cause");
|
|
94
|
+
const err = new Class("msg", inner);
|
|
95
95
|
expect(err.error).toBe(inner);
|
|
96
|
-
expect(err.message).toBe(
|
|
96
|
+
expect(err.message).toBe("msg");
|
|
97
97
|
});
|
|
98
98
|
});
|
|
99
99
|
}
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import { describe, it, expect } from
|
|
2
|
-
import { u8ToB64, b64ToU8 } from
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { u8ToB64, b64ToU8 } from "../helpers";
|
|
3
3
|
|
|
4
|
-
describe(
|
|
5
|
-
it(
|
|
4
|
+
describe("u8ToB64", () => {
|
|
5
|
+
it("encodes a known value correctly", () => {
|
|
6
6
|
const bytes = new Uint8Array([72, 101, 108, 108, 111]); // "Hello"
|
|
7
|
-
expect(u8ToB64(bytes)).toBe(
|
|
7
|
+
expect(u8ToB64(bytes)).toBe("SGVsbG8=");
|
|
8
8
|
});
|
|
9
9
|
|
|
10
|
-
it(
|
|
11
|
-
expect(u8ToB64(new Uint8Array([]))).toBe(
|
|
10
|
+
it("encodes an empty array", () => {
|
|
11
|
+
expect(u8ToB64(new Uint8Array([]))).toBe("");
|
|
12
12
|
});
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
describe(
|
|
16
|
-
it(
|
|
17
|
-
const result = b64ToU8(
|
|
15
|
+
describe("b64ToU8", () => {
|
|
16
|
+
it("decodes a known value correctly", () => {
|
|
17
|
+
const result = b64ToU8("SGVsbG8=");
|
|
18
18
|
expect(result).toEqual(new Uint8Array([72, 101, 108, 108, 111]));
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
it(
|
|
22
|
-
expect(b64ToU8(
|
|
21
|
+
it("decodes an empty string", () => {
|
|
22
|
+
expect(b64ToU8("")).toEqual(new Uint8Array([]));
|
|
23
23
|
});
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
describe(
|
|
27
|
-
it(
|
|
26
|
+
describe("roundtrip", () => {
|
|
27
|
+
it("encode then decode returns original bytes", () => {
|
|
28
28
|
const original = new Uint8Array([0, 1, 127, 128, 255]);
|
|
29
29
|
const decoded = b64ToU8(u8ToB64(original));
|
|
30
30
|
expect(decoded).toEqual(original);
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
-
it(
|
|
33
|
+
it("handles a large array (256 bytes)", () => {
|
|
34
34
|
const original = new Uint8Array(256);
|
|
35
35
|
for (let i = 0; i < 256; i++) original[i] = i;
|
|
36
36
|
const decoded = b64ToU8(u8ToB64(original));
|
package/__tests__/signer.test.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { describe, it, expect } from
|
|
2
|
-
import type { GuardianInfo } from
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import type { GuardianInfo } from "../types";
|
|
3
3
|
|
|
4
|
-
describe(
|
|
5
|
-
it(
|
|
4
|
+
describe("GuardianInfo", () => {
|
|
5
|
+
it("has the agreed shape", () => {
|
|
6
6
|
const g: GuardianInfo = {
|
|
7
7
|
isGuardianAccount: false,
|
|
8
8
|
guardianEndpoint: null,
|
|
@@ -11,10 +11,10 @@ describe('GuardianInfo', () => {
|
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
expect(Object.keys(g).sort()).toEqual([
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
"guardianEndpoint",
|
|
15
|
+
"guardianProvider",
|
|
16
|
+
"guardianSyncStatus",
|
|
17
|
+
"isGuardianAccount",
|
|
18
18
|
]);
|
|
19
19
|
});
|
|
20
20
|
});
|
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from
|
|
1
|
+
import { describe, it, expect, vi } from "vitest";
|
|
2
2
|
import {
|
|
3
3
|
SendTransaction,
|
|
4
4
|
ConsumeTransaction,
|
|
5
5
|
CustomTransaction,
|
|
6
6
|
Transaction,
|
|
7
7
|
TransactionType,
|
|
8
|
-
} from
|
|
9
|
-
import { u8ToB64 } from
|
|
8
|
+
} from "../transaction";
|
|
9
|
+
import { u8ToB64 } from "../helpers";
|
|
10
10
|
|
|
11
|
-
describe(
|
|
12
|
-
it(
|
|
13
|
-
expect(TransactionType.Send).toBe(
|
|
14
|
-
expect(TransactionType.Consume).toBe(
|
|
15
|
-
expect(TransactionType.Custom).toBe(
|
|
11
|
+
describe("TransactionType enum", () => {
|
|
12
|
+
it("has correct values", () => {
|
|
13
|
+
expect(TransactionType.Send).toBe("send");
|
|
14
|
+
expect(TransactionType.Consume).toBe("consume");
|
|
15
|
+
expect(TransactionType.Custom).toBe("custom");
|
|
16
16
|
});
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
-
describe(
|
|
20
|
-
it(
|
|
19
|
+
describe("SendTransaction", () => {
|
|
20
|
+
it("sets all fields correctly", () => {
|
|
21
21
|
const tx = new SendTransaction(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
"sender-addr",
|
|
23
|
+
"recipient-addr",
|
|
24
|
+
"faucet-123",
|
|
25
|
+
"public",
|
|
26
26
|
1000
|
|
27
27
|
);
|
|
28
|
-
expect(tx.senderAddress).toBe(
|
|
29
|
-
expect(tx.recipientAddress).toBe(
|
|
30
|
-
expect(tx.faucetId).toBe(
|
|
31
|
-
expect(tx.noteType).toBe(
|
|
28
|
+
expect(tx.senderAddress).toBe("sender-addr");
|
|
29
|
+
expect(tx.recipientAddress).toBe("recipient-addr");
|
|
30
|
+
expect(tx.faucetId).toBe("faucet-123");
|
|
31
|
+
expect(tx.noteType).toBe("public");
|
|
32
32
|
expect(tx.amount).toBe(1000);
|
|
33
33
|
expect(tx.recallBlocks).toBeUndefined();
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
-
it(
|
|
36
|
+
it("sets optional recallBlocks", () => {
|
|
37
37
|
const tx = new SendTransaction(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
"sender",
|
|
39
|
+
"recipient",
|
|
40
|
+
"faucet",
|
|
41
|
+
"private",
|
|
42
42
|
500,
|
|
43
43
|
10
|
|
44
44
|
);
|
|
@@ -46,63 +46,63 @@ describe('SendTransaction', () => {
|
|
|
46
46
|
});
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
-
describe(
|
|
50
|
-
it(
|
|
51
|
-
const tx = new ConsumeTransaction(
|
|
52
|
-
expect(tx.faucetId).toBe(
|
|
53
|
-
expect(tx.noteId).toBe(
|
|
54
|
-
expect(tx.noteType).toBe(
|
|
49
|
+
describe("ConsumeTransaction", () => {
|
|
50
|
+
it("sets fields correctly", () => {
|
|
51
|
+
const tx = new ConsumeTransaction("faucet-1", "note-1", "public", 100);
|
|
52
|
+
expect(tx.faucetId).toBe("faucet-1");
|
|
53
|
+
expect(tx.noteId).toBe("note-1");
|
|
54
|
+
expect(tx.noteType).toBe("public");
|
|
55
55
|
expect(tx.amount).toBe(100);
|
|
56
56
|
expect(tx.noteBytes).toBeUndefined();
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
it(
|
|
59
|
+
it("converts noteBytes Uint8Array to base64", () => {
|
|
60
60
|
const bytes = new Uint8Array([1, 2, 3]);
|
|
61
|
-
const tx = new ConsumeTransaction(
|
|
61
|
+
const tx = new ConsumeTransaction("faucet", "note", "private", 50, bytes);
|
|
62
62
|
expect(tx.noteBytes).toBe(u8ToB64(bytes));
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
-
it(
|
|
66
|
-
const tx = new ConsumeTransaction(
|
|
65
|
+
it("leaves noteBytes undefined when not provided", () => {
|
|
66
|
+
const tx = new ConsumeTransaction("faucet", "note", "public", 50);
|
|
67
67
|
expect(tx.noteBytes).toBeUndefined();
|
|
68
68
|
});
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
-
describe(
|
|
72
|
-
it(
|
|
71
|
+
describe("CustomTransaction", () => {
|
|
72
|
+
it("serializes transactionRequest to base64", () => {
|
|
73
73
|
const mockBytes = new Uint8Array([10, 20, 30]);
|
|
74
74
|
const mockRequest = {
|
|
75
75
|
serialize: vi.fn().mockReturnValue(mockBytes),
|
|
76
76
|
} as any;
|
|
77
77
|
|
|
78
|
-
const tx = new CustomTransaction(
|
|
78
|
+
const tx = new CustomTransaction("addr", "recipient", mockRequest);
|
|
79
79
|
expect(mockRequest.serialize).toHaveBeenCalled();
|
|
80
80
|
expect(tx.transactionRequest).toBe(u8ToB64(mockBytes));
|
|
81
|
-
expect(tx.address).toBe(
|
|
82
|
-
expect(tx.recipientAddress).toBe(
|
|
81
|
+
expect(tx.address).toBe("addr");
|
|
82
|
+
expect(tx.recipientAddress).toBe("recipient");
|
|
83
83
|
});
|
|
84
84
|
|
|
85
|
-
it(
|
|
85
|
+
it("sets optional inputNoteIds", () => {
|
|
86
86
|
const mockRequest = {
|
|
87
87
|
serialize: vi.fn().mockReturnValue(new Uint8Array([1])),
|
|
88
88
|
} as any;
|
|
89
|
-
const tx = new CustomTransaction(
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
const tx = new CustomTransaction("addr", "recipient", mockRequest, [
|
|
90
|
+
"id1",
|
|
91
|
+
"id2",
|
|
92
92
|
]);
|
|
93
|
-
expect(tx.inputNoteIds).toEqual([
|
|
93
|
+
expect(tx.inputNoteIds).toEqual(["id1", "id2"]);
|
|
94
94
|
});
|
|
95
95
|
|
|
96
|
-
it(
|
|
96
|
+
it("converts importNotes from Uint8Array[] to base64 strings", () => {
|
|
97
97
|
const mockRequest = {
|
|
98
98
|
serialize: vi.fn().mockReturnValue(new Uint8Array([1])),
|
|
99
99
|
} as any;
|
|
100
100
|
const noteBytes = [new Uint8Array([4, 5]), new Uint8Array([6, 7])];
|
|
101
101
|
const tx = new CustomTransaction(
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
"addr",
|
|
103
|
+
"recipient",
|
|
104
104
|
mockRequest,
|
|
105
|
-
[
|
|
105
|
+
["id1"],
|
|
106
106
|
noteBytes
|
|
107
107
|
);
|
|
108
108
|
expect(tx.importNotes).toEqual([
|
|
@@ -111,53 +111,53 @@ describe('CustomTransaction', () => {
|
|
|
111
111
|
]);
|
|
112
112
|
});
|
|
113
113
|
|
|
114
|
-
it(
|
|
114
|
+
it("leaves optional fields undefined when not provided", () => {
|
|
115
115
|
const mockRequest = {
|
|
116
116
|
serialize: vi.fn().mockReturnValue(new Uint8Array([1])),
|
|
117
117
|
} as any;
|
|
118
|
-
const tx = new CustomTransaction(
|
|
118
|
+
const tx = new CustomTransaction("addr", "recipient", mockRequest);
|
|
119
119
|
expect(tx.inputNoteIds).toBeUndefined();
|
|
120
120
|
expect(tx.importNotes).toBeUndefined();
|
|
121
121
|
});
|
|
122
122
|
});
|
|
123
123
|
|
|
124
|
-
describe(
|
|
125
|
-
it(
|
|
124
|
+
describe("Transaction factory", () => {
|
|
125
|
+
it("createSendTransaction returns correct type and payload", () => {
|
|
126
126
|
const tx = Transaction.createSendTransaction(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
127
|
+
"sender",
|
|
128
|
+
"recipient",
|
|
129
|
+
"faucet",
|
|
130
|
+
"public",
|
|
131
131
|
100
|
|
132
132
|
);
|
|
133
133
|
expect(tx.type).toBe(TransactionType.Send);
|
|
134
134
|
expect(tx.payload).toBeInstanceOf(SendTransaction);
|
|
135
135
|
const payload = tx.payload as SendTransaction;
|
|
136
|
-
expect(payload.senderAddress).toBe(
|
|
136
|
+
expect(payload.senderAddress).toBe("sender");
|
|
137
137
|
expect(payload.amount).toBe(100);
|
|
138
138
|
});
|
|
139
139
|
|
|
140
|
-
it(
|
|
140
|
+
it("createConsumeTransaction returns correct type and payload", () => {
|
|
141
141
|
const tx = Transaction.createConsumeTransaction(
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
"faucet",
|
|
143
|
+
"note-id",
|
|
144
|
+
"private",
|
|
145
145
|
200
|
|
146
146
|
);
|
|
147
147
|
expect(tx.type).toBe(TransactionType.Consume);
|
|
148
148
|
expect(tx.payload).toBeInstanceOf(ConsumeTransaction);
|
|
149
149
|
const payload = tx.payload as ConsumeTransaction;
|
|
150
|
-
expect(payload.faucetId).toBe(
|
|
151
|
-
expect(payload.noteId).toBe(
|
|
150
|
+
expect(payload.faucetId).toBe("faucet");
|
|
151
|
+
expect(payload.noteId).toBe("note-id");
|
|
152
152
|
});
|
|
153
153
|
|
|
154
|
-
it(
|
|
154
|
+
it("createCustomTransaction returns correct type and payload", () => {
|
|
155
155
|
const mockRequest = {
|
|
156
156
|
serialize: vi.fn().mockReturnValue(new Uint8Array([1, 2])),
|
|
157
157
|
} as any;
|
|
158
158
|
const tx = Transaction.createCustomTransaction(
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
"addr",
|
|
160
|
+
"recipient",
|
|
161
161
|
mockRequest
|
|
162
162
|
);
|
|
163
163
|
expect(tx.type).toBe(TransactionType.Custom);
|
package/adapter.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import EventEmitter from
|
|
2
|
-
import type { WalletError } from
|
|
1
|
+
import EventEmitter from "eventemitter3";
|
|
2
|
+
import type { WalletError } from "./errors";
|
|
3
3
|
import type {
|
|
4
4
|
AllowedPrivateData,
|
|
5
5
|
PrivateDataPermission,
|
|
6
6
|
SupportedTransactionVersions,
|
|
7
7
|
WalletAdapterNetwork,
|
|
8
|
-
} from
|
|
8
|
+
} from "./types";
|
|
9
9
|
|
|
10
10
|
export { EventEmitter };
|
|
11
11
|
|
|
@@ -19,7 +19,7 @@ export interface WalletAdapterEvents {
|
|
|
19
19
|
// WalletName is a nominal type that wallet adapters should use, e.g. `'MyCryptoWallet' as WalletName<'MyCryptoWallet'>`
|
|
20
20
|
// https://medium.com/@KevinBGreene/surviving-the-typescript-ecosystem-branding-and-type-tagging-6cf6e516523d
|
|
21
21
|
export type WalletName<T extends string = string> = T & {
|
|
22
|
-
__brand__:
|
|
22
|
+
__brand__: "WalletName";
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
export interface WalletAdapterProps<Name extends string = string> {
|
|
@@ -59,18 +59,18 @@ export enum WalletReadyState {
|
|
|
59
59
|
* that they've injected into the global context. If such an API is present,
|
|
60
60
|
* we consider the wallet to have been installed.
|
|
61
61
|
*/
|
|
62
|
-
Installed =
|
|
63
|
-
NotDetected =
|
|
62
|
+
Installed = "Installed",
|
|
63
|
+
NotDetected = "NotDetected",
|
|
64
64
|
/**
|
|
65
65
|
* Loadable wallets are always available to you. Since you can load them at
|
|
66
66
|
* any time, it's meaningless to say that they have been detected.
|
|
67
67
|
*/
|
|
68
|
-
Loadable =
|
|
68
|
+
Loadable = "Loadable",
|
|
69
69
|
/**
|
|
70
70
|
* If a wallet is not supported on a given platform (eg. server-rendering, or
|
|
71
71
|
* mobile) then it will stay in the `Unsupported` state.
|
|
72
72
|
*/
|
|
73
|
-
Unsupported =
|
|
73
|
+
Unsupported = "Unsupported",
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
export abstract class BaseWalletAdapter<Name extends string = string>
|
|
@@ -100,7 +100,7 @@ export abstract class BaseWalletAdapter<Name extends string = string>
|
|
|
100
100
|
|
|
101
101
|
export function scopePollingDetectionStrategy(detect: () => boolean): void {
|
|
102
102
|
// Early return when server-side rendering
|
|
103
|
-
if (typeof window ===
|
|
103
|
+
if (typeof window === "undefined" || typeof document === "undefined") return;
|
|
104
104
|
|
|
105
105
|
const disposers: (() => void)[] = [];
|
|
106
106
|
|
|
@@ -122,23 +122,23 @@ export function scopePollingDetectionStrategy(detect: () => boolean): void {
|
|
|
122
122
|
// Strategy #2: Detect as soon as the DOM becomes 'ready'/'interactive'.
|
|
123
123
|
if (
|
|
124
124
|
// Implies that `DOMContentLoaded` has not yet fired.
|
|
125
|
-
document.readyState ===
|
|
125
|
+
document.readyState === "loading"
|
|
126
126
|
) {
|
|
127
|
-
document.addEventListener(
|
|
127
|
+
document.addEventListener("DOMContentLoaded", detectAndDispose, {
|
|
128
128
|
once: true,
|
|
129
129
|
});
|
|
130
130
|
disposers.push(() =>
|
|
131
|
-
document.removeEventListener(
|
|
131
|
+
document.removeEventListener("DOMContentLoaded", detectAndDispose)
|
|
132
132
|
);
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
// Strategy #3: Detect after the `window` has fully loaded.
|
|
136
136
|
if (
|
|
137
137
|
// If the `complete` state has been reached, we're too late.
|
|
138
|
-
document.readyState !==
|
|
138
|
+
document.readyState !== "complete"
|
|
139
139
|
) {
|
|
140
|
-
window.addEventListener(
|
|
141
|
-
disposers.push(() => window.removeEventListener(
|
|
140
|
+
window.addEventListener("load", detectAndDispose, { once: true });
|
|
141
|
+
disposers.push(() => window.removeEventListener("load", detectAndDispose));
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
// Strategy #4: Detect synchronously, now.
|