@cardano-slips/flow 0.0.2 → 0.1.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 +27 -0
- package/dist/address.d.ts +13 -0
- package/dist/address.d.ts.map +1 -0
- package/dist/address.js +54 -0
- package/dist/address.js.map +1 -0
- package/dist/cip30.d.ts +66 -0
- package/dist/cip30.d.ts.map +1 -0
- package/dist/cip30.js +53 -0
- package/dist/cip30.js.map +1 -0
- package/dist/connect.d.ts +45 -0
- package/dist/connect.d.ts.map +1 -0
- package/dist/connect.js +73 -0
- package/dist/connect.js.map +1 -0
- package/dist/discovery.d.ts +37 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +71 -0
- package/dist/discovery.js.map +1 -0
- package/dist/index.d.ts +12 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/registry.d.ts +18 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +15 -0
- package/dist/registry.js.map +1 -0
- package/dist/tokens.css +184 -0
- package/dist/wallet-error.d.ts +48 -0
- package/dist/wallet-error.d.ts.map +1 -0
- package/dist/wallet-error.js +31 -0
- package/dist/wallet-error.js.map +1 -0
- package/package.json +6 -4
- package/src/address.ts +69 -0
- package/src/cip30.ts +94 -0
- package/src/connect.ts +136 -0
- package/src/discovery.ts +92 -0
- package/src/index.ts +12 -7
- package/src/registry.ts +32 -0
- package/src/tokens.css +184 -0
- package/src/wallet-error.ts +68 -0
package/README.md
CHANGED
|
@@ -30,6 +30,33 @@ These components are meant to be dropped into someone else's page. No fixed posi
|
|
|
30
30
|
|
|
31
31
|
React is a **peer** dependency: your copy is the one that renders, and a second copy in the tree is the oldest breakage in the ecosystem.
|
|
32
32
|
|
|
33
|
+
## Tokens
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import "@cardano-slips/flow/tokens.css"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<div class="slip-root">…</div>
|
|
41
|
+
<div class="slip-root" data-theme="dark">…</div>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The tokens are scoped to `slip-root` rather than `:root`, because a package that writes `--ink` onto the document redefines whatever the host already called that. Put the class on the element that wraps the Slip. There is no reset in the file and no rule that selects an element, so an inherited font stack stays where it is until something of ours asks for a token.
|
|
45
|
+
|
|
46
|
+
`data-theme="dark"` is the whole of the theme rule: it rebinds the roles — surfaces, ink, accent and the semantic three — so a component writes `var(--ink)` once and is right in both. A component choosing between a light token and a dark one is a component deciding the rule, and two of them will decide it differently. Whether dark follows the operating system is not settled by the design sheet, so it is not decided here either; the attribute is the only way in.
|
|
47
|
+
|
|
48
|
+
Three families of surface, and the difference is the point:
|
|
49
|
+
|
|
50
|
+
| Family | What it is |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| `--page`, `--card` | the ordinary ground, and what lifts off it |
|
|
53
|
+
| `--vault-*` | the transaction preview, which separates itself by surface and border rather than by being dark |
|
|
54
|
+
| `--dark-*` | code blocks and the Open Graph card — dark in **both** themes, so they are the one thing the theme does not touch |
|
|
55
|
+
|
|
56
|
+
Type arrives as whole roles — `font: var(--type-card-title)` carries family, weight, size and line-height together — because the sheet settles a pairing, not a size. Depth is a border; there is no shadow token.
|
|
57
|
+
|
|
58
|
+
Two rules the tests keep: no colour is written anywhere but `tokens.css`, and the design sheet's contrast audit is recomputed against these values rather than trusted. `--accent-fill` is a fill — it does not clear AA on a light card, which is why `--accent-text` exists for any accent-coloured word, and it stays a fill in the dark theme where the ratio alone would allow otherwise.
|
|
59
|
+
|
|
33
60
|
## Entry point
|
|
34
61
|
|
|
35
62
|
One export, the package root. Deep imports into `dist/` are not a supported surface, so moving a file is never a breaking change:
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Either } from "effect";
|
|
2
|
+
/** CIP-30's `getNetworkId`: 1 is mainnet, 0 is every test network. */
|
|
3
|
+
export type NetworkId = 0 | 1;
|
|
4
|
+
export type WalletAddress = {
|
|
5
|
+
readonly bech32: string;
|
|
6
|
+
readonly networkId: NetworkId;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Reads what CIP-30 returned. `Either` and not a throw: this runs on whatever a
|
|
10
|
+
* browser extension chose to send, and every refusal reaches a person as words.
|
|
11
|
+
*/
|
|
12
|
+
export declare const readWalletAddress: (hex: string) => Either.Either<WalletAddress, string>;
|
|
13
|
+
//# sourceMappingURL=address.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../src/address.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAA;AAEvC,sEAAsE;AACtE,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,CAAA;AAE7B,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;CAC9B,CAAA;AA0BD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAqBlF,CAAA"}
|
package/dist/address.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CIP-30 hands addresses back as hex; the endpoint is sent bech32, because that
|
|
3
|
+
* is what a `BuildRequest` carries and what a person can recognise. The
|
|
4
|
+
* conversion is also the second statement of network — the header byte says
|
|
5
|
+
* which chain the address is for, and a wallet whose `getNetworkId` disagrees
|
|
6
|
+
* with its own address has answered two ways.
|
|
7
|
+
*/
|
|
8
|
+
import { PaymentAddress } from "@cardano-slips/core";
|
|
9
|
+
import { encodeBech32 } from "@cardano-slips/verifier";
|
|
10
|
+
import { Either, Schema } from "effect";
|
|
11
|
+
const decodePaymentAddress = Schema.decodeUnknownEither(PaymentAddress);
|
|
12
|
+
const refuse = (detail) => Either.left(detail);
|
|
13
|
+
const fromHex = (hex) => {
|
|
14
|
+
if (hex.length === 0 || hex.length % 2 !== 0 || !/^[0-9a-fA-F]+$/.test(hex))
|
|
15
|
+
return undefined;
|
|
16
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
17
|
+
for (let index = 0; index < bytes.length; index++)
|
|
18
|
+
bytes[index] = Number.parseInt(hex.slice(index * 2, index * 2 + 2), 16);
|
|
19
|
+
return bytes;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* CIP-30 calls the value "the CBOR of the address" and wallets ship the address
|
|
23
|
+
* bytes bare. Both are accepted, and they cannot be confused: `0x58` as a first
|
|
24
|
+
* byte is a CBOR byte string of up to 255 bytes, and as an address header it
|
|
25
|
+
* would claim network 8, which does not exist.
|
|
26
|
+
*/
|
|
27
|
+
const unwrapCbor = (bytes) => bytes.length > 2 && bytes[0] === 0x58 && bytes[1] === bytes.length - 2 ? bytes.subarray(2) : bytes;
|
|
28
|
+
/** CIP-19: the header's high nibble is the address type, the low nibble the network. Types 0-7 can hold a payment. */
|
|
29
|
+
const LAST_PAYMENT_TYPE = 7;
|
|
30
|
+
/**
|
|
31
|
+
* Reads what CIP-30 returned. `Either` and not a throw: this runs on whatever a
|
|
32
|
+
* browser extension chose to send, and every refusal reaches a person as words.
|
|
33
|
+
*/
|
|
34
|
+
export const readWalletAddress = (hex) => {
|
|
35
|
+
const raw = fromHex(hex.trim());
|
|
36
|
+
if (raw === undefined)
|
|
37
|
+
return refuse(`${hex.slice(0, 16)}… is not hex`);
|
|
38
|
+
const bytes = unwrapCbor(raw);
|
|
39
|
+
const header = bytes[0];
|
|
40
|
+
const networkId = header & 0x0f;
|
|
41
|
+
if (networkId !== 0 && networkId !== 1)
|
|
42
|
+
return refuse(`the address header names network ${networkId}`);
|
|
43
|
+
const type = header >> 4;
|
|
44
|
+
if (type > LAST_PAYMENT_TYPE) {
|
|
45
|
+
// A reward address (14, 15) or a Byron address (8) cannot receive change.
|
|
46
|
+
return refuse(`address type ${type} cannot hold a payment`);
|
|
47
|
+
}
|
|
48
|
+
const bech32 = encodeBech32(networkId === 1 ? "addr" : "addr_test", bytes);
|
|
49
|
+
return Either.match(decodePaymentAddress(bech32), {
|
|
50
|
+
onLeft: () => refuse(`${bech32.slice(0, 16)}… is not a payment address`),
|
|
51
|
+
onRight: () => Either.right({ bech32, networkId: networkId })
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=address.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address.js","sourceRoot":"","sources":["../src/address.ts"],"names":[],"mappings":"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"}
|
package/dist/cip30.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CIP-30 surface this client calls, declared here because evolution-sdk's
|
|
3
|
+
* `WalletApi` omits `getChangeAddress`, `getCollateral` and `getNetworkId`
|
|
4
|
+
* while the object a wallet actually hands back carries all three (ADR-0004).
|
|
5
|
+
* A typing we assert rather than one the SDK guarantees, so it is proved
|
|
6
|
+
* against a stubbed provider rather than trusted.
|
|
7
|
+
*/
|
|
8
|
+
/** Hex-encoded CBOR: the only form CIP-30 speaks, and the form `verifier` decodes. */
|
|
9
|
+
export type CborHex = string;
|
|
10
|
+
export type Paginate = {
|
|
11
|
+
readonly page: number;
|
|
12
|
+
readonly limit: number;
|
|
13
|
+
};
|
|
14
|
+
export type SignedData = {
|
|
15
|
+
readonly signature: CborHex;
|
|
16
|
+
readonly key: CborHex;
|
|
17
|
+
};
|
|
18
|
+
export interface Cip30Api {
|
|
19
|
+
readonly getNetworkId: () => Promise<number>;
|
|
20
|
+
readonly getChangeAddress: () => Promise<CborHex>;
|
|
21
|
+
readonly getUsedAddresses: (paginate?: Paginate) => Promise<ReadonlyArray<CborHex>>;
|
|
22
|
+
readonly getUnusedAddresses: () => Promise<ReadonlyArray<CborHex>>;
|
|
23
|
+
readonly getRewardAddresses: () => Promise<ReadonlyArray<CborHex>>;
|
|
24
|
+
readonly getBalance: () => Promise<CborHex>;
|
|
25
|
+
/** `null` where the wallet has nothing to give, per CIP-30. */
|
|
26
|
+
readonly getUtxos: (amount?: CborHex, paginate?: Paginate) => Promise<ReadonlyArray<CborHex> | null>;
|
|
27
|
+
readonly getCollateral: (params?: {
|
|
28
|
+
readonly amount: CborHex;
|
|
29
|
+
}) => Promise<ReadonlyArray<CborHex> | null>;
|
|
30
|
+
/** Returns a **witness set**, never a signed transaction — invariant 4 is CIP-30's own shape. */
|
|
31
|
+
readonly signTx: (tx: CborHex, partialSign?: boolean) => Promise<CborHex>;
|
|
32
|
+
readonly signData: (address: CborHex, payload: CborHex) => Promise<SignedData>;
|
|
33
|
+
readonly submitTx: (tx: CborHex) => Promise<string>;
|
|
34
|
+
}
|
|
35
|
+
/** What an extension injects at `window.cardano[key]`, before anyone calls `enable()`. */
|
|
36
|
+
export interface Cip30Provider {
|
|
37
|
+
readonly apiVersion: string;
|
|
38
|
+
readonly name: string;
|
|
39
|
+
readonly icon: string;
|
|
40
|
+
readonly supportedExtensions?: ReadonlyArray<{
|
|
41
|
+
readonly cip: number;
|
|
42
|
+
}>;
|
|
43
|
+
readonly enable: (extensions?: ReadonlyArray<{
|
|
44
|
+
readonly cip: number;
|
|
45
|
+
}>) => Promise<Cip30Api>;
|
|
46
|
+
readonly isEnabled: () => Promise<boolean>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Shape, not name: `window.cardano` is a namespace anything may write to, and a
|
|
50
|
+
* key that does not answer these four is not a connector whatever it is called.
|
|
51
|
+
*/
|
|
52
|
+
export declare const isCip30Provider: (value: unknown) => value is Cip30Provider;
|
|
53
|
+
export declare const isCip30Api: (value: unknown) => value is Cip30Api;
|
|
54
|
+
/** CIP-30's `APIError`, kept whole: the numeric code is what says a person declined. */
|
|
55
|
+
export type Cip30ApiError = {
|
|
56
|
+
readonly code: number;
|
|
57
|
+
readonly info: string;
|
|
58
|
+
};
|
|
59
|
+
/** The four `APIError` codes CIP-30 defines. Anything else is passed through as its number. */
|
|
60
|
+
export declare const apiErrorNames: Readonly<Record<number, string>>;
|
|
61
|
+
/** `-3` is the person saying no, which is not a fault and must not be shown as one. */
|
|
62
|
+
export declare const REFUSED = -3;
|
|
63
|
+
/** A wallet rejects with a plain `{ code, info }` object, not an `Error`. */
|
|
64
|
+
export declare const readApiError: (cause: unknown) => Cip30ApiError | undefined;
|
|
65
|
+
export declare const describeApiError: (error: Cip30ApiError) => string;
|
|
66
|
+
//# sourceMappingURL=cip30.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cip30.d.ts","sourceRoot":"","sources":["../src/cip30.ts"],"names":[],"mappings":"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"}
|
package/dist/cip30.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CIP-30 surface this client calls, declared here because evolution-sdk's
|
|
3
|
+
* `WalletApi` omits `getChangeAddress`, `getCollateral` and `getNetworkId`
|
|
4
|
+
* while the object a wallet actually hands back carries all three (ADR-0004).
|
|
5
|
+
* A typing we assert rather than one the SDK guarantees, so it is proved
|
|
6
|
+
* against a stubbed provider rather than trusted.
|
|
7
|
+
*/
|
|
8
|
+
const isFunction = (value) => typeof value === "function";
|
|
9
|
+
/**
|
|
10
|
+
* Shape, not name: `window.cardano` is a namespace anything may write to, and a
|
|
11
|
+
* key that does not answer these four is not a connector whatever it is called.
|
|
12
|
+
*/
|
|
13
|
+
export const isCip30Provider = (value) => {
|
|
14
|
+
if (typeof value !== "object" || value === null)
|
|
15
|
+
return false;
|
|
16
|
+
const candidate = value;
|
|
17
|
+
return (isFunction(candidate.enable) &&
|
|
18
|
+
isFunction(candidate.isEnabled) &&
|
|
19
|
+
typeof candidate.name === "string" &&
|
|
20
|
+
typeof candidate.apiVersion === "string");
|
|
21
|
+
};
|
|
22
|
+
/** The methods we call. A provider may enable and still not answer them. */
|
|
23
|
+
const apiMethods = ["getNetworkId", "getChangeAddress", "getUsedAddresses", "getUtxos", "signTx", "submitTx"];
|
|
24
|
+
export const isCip30Api = (value) => {
|
|
25
|
+
if (typeof value !== "object" || value === null)
|
|
26
|
+
return false;
|
|
27
|
+
const candidate = value;
|
|
28
|
+
return apiMethods.every((method) => isFunction(candidate[method]));
|
|
29
|
+
};
|
|
30
|
+
/** The four `APIError` codes CIP-30 defines. Anything else is passed through as its number. */
|
|
31
|
+
export const apiErrorNames = {
|
|
32
|
+
[-1]: "InvalidRequest",
|
|
33
|
+
[-2]: "InternalError",
|
|
34
|
+
[-3]: "Refused",
|
|
35
|
+
[-4]: "AccountChange"
|
|
36
|
+
};
|
|
37
|
+
/** `-3` is the person saying no, which is not a fault and must not be shown as one. */
|
|
38
|
+
export const REFUSED = -3;
|
|
39
|
+
/** A wallet rejects with a plain `{ code, info }` object, not an `Error`. */
|
|
40
|
+
export const readApiError = (cause) => {
|
|
41
|
+
if (typeof cause !== "object" || cause === null)
|
|
42
|
+
return undefined;
|
|
43
|
+
const candidate = cause;
|
|
44
|
+
if (typeof candidate.code !== "number")
|
|
45
|
+
return undefined;
|
|
46
|
+
return { code: candidate.code, info: typeof candidate.info === "string" ? candidate.info : "" };
|
|
47
|
+
};
|
|
48
|
+
export const describeApiError = (error) => {
|
|
49
|
+
const name = apiErrorNames[error.code];
|
|
50
|
+
const label = name === undefined ? `code ${error.code}` : name;
|
|
51
|
+
return error.info === "" ? label : `${label}: ${error.info}`;
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=cip30.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cip30.js","sourceRoot":"","sources":["../src/cip30.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmCH,MAAM,UAAU,GAAG,CAAC,KAAc,EAAW,EAAE,CAAC,OAAO,KAAK,KAAK,UAAU,CAAA;AAE3E;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAc,EAA0B,EAAE;IACxE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IAC7D,MAAM,SAAS,GAAG,KAAgC,CAAA;IAClD,OAAO,CACL,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC;QAC5B,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC;QAC/B,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ;QAClC,OAAO,SAAS,CAAC,UAAU,KAAK,QAAQ,CACzC,CAAA;AACH,CAAC,CAAA;AAED,4EAA4E;AAC5E,MAAM,UAAU,GAAG,CAAC,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,CAAU,CAAA;AAEtH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAc,EAAqB,EAAE;IAC9D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAA;IAC7D,MAAM,SAAS,GAAG,KAAgC,CAAA;IAClD,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;AACpE,CAAC,CAAA;AAKD,+FAA+F;AAC/F,MAAM,CAAC,MAAM,aAAa,GAAqC;IAC7D,CAAC,CAAC,CAAC,CAAC,EAAE,gBAAgB;IACtB,CAAC,CAAC,CAAC,CAAC,EAAE,eAAe;IACrB,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS;IACf,CAAC,CAAC,CAAC,CAAC,EAAE,eAAe;CACtB,CAAA;AAED,uFAAuF;AACvF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC,CAAA;AAEzB,6EAA6E;AAC7E,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAc,EAA6B,EAAE;IACxE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,SAAS,CAAA;IACjE,MAAM,SAAS,GAAG,KAAgC,CAAA;IAClD,IAAI,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IACxD,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;AACjG,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAoB,EAAU,EAAE;IAC/D,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACtC,MAAM,KAAK,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IAC9D,OAAO,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,KAAK,CAAC,IAAI,EAAE,CAAA;AAC9D,CAAC,CAAA"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `enable()` and the three answers a connection is not usable without: the API
|
|
3
|
+
* object, the network, and the change address. Everything downstream of here —
|
|
4
|
+
* UTxOs, balancing, signing — goes through evolution-sdk with this API object
|
|
5
|
+
* (ADR-0004).
|
|
6
|
+
*/
|
|
7
|
+
import { type Network } from "@cardano-slips/core";
|
|
8
|
+
import { Effect } from "effect";
|
|
9
|
+
import { type NetworkId } from "./address.js";
|
|
10
|
+
import { type Cip30Api } from "./cip30.js";
|
|
11
|
+
import { type DiscoveredWallet } from "./discovery.js";
|
|
12
|
+
import { type WalletConnectError } from "./wallet-error.js";
|
|
13
|
+
export type ConnectOptions = {
|
|
14
|
+
/** The network the Slip declares. The wallet is held to it, not asked for it. */
|
|
15
|
+
readonly network: Network;
|
|
16
|
+
/** Where `cardano` lives. Defaults to the global object, so a test never needs one. */
|
|
17
|
+
readonly host?: unknown;
|
|
18
|
+
/** CIP extensions to ask for. A wallet may grant fewer, and none of ours are required. */
|
|
19
|
+
readonly extensions?: ReadonlyArray<{
|
|
20
|
+
readonly cip: number;
|
|
21
|
+
}>;
|
|
22
|
+
};
|
|
23
|
+
export type ConnectedWallet = {
|
|
24
|
+
readonly wallet: DiscoveredWallet;
|
|
25
|
+
readonly api: Cip30Api;
|
|
26
|
+
/** The Slip's network, now known to be the wallet's as well. */
|
|
27
|
+
readonly network: Network;
|
|
28
|
+
readonly networkId: NetworkId;
|
|
29
|
+
/** Bech32, ready for a `BuildRequest`. */
|
|
30
|
+
readonly changeAddress: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* A CIP-19 address separates mainnet from testnet and no further, so this is
|
|
34
|
+
* every network id there is — preprod and preview are one value here. Telling
|
|
35
|
+
* them apart is exactly why a Slip states its network by name (`core/types.ts`).
|
|
36
|
+
*/
|
|
37
|
+
export declare const networkIdFor: (network: Network) => NetworkId;
|
|
38
|
+
/**
|
|
39
|
+
* Connects, or says why not. The network check happens here rather than in a
|
|
40
|
+
* component because it decides whether there is a connection at all: a wallet
|
|
41
|
+
* on another chain cannot sign this Slip's transaction, and letting the flow
|
|
42
|
+
* continue only moves the failure to where it costs a person more.
|
|
43
|
+
*/
|
|
44
|
+
export declare const connectWallet: (key: string, options: ConnectOptions) => Effect.Effect<ConnectedWallet, WalletConnectError>;
|
|
45
|
+
//# sourceMappingURL=connect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,cAAc,CAAA;AAChE,OAAO,EAAE,KAAK,QAAQ,EAAuD,MAAM,YAAY,CAAA;AAC/F,OAAO,EAAE,KAAK,gBAAgB,EAA6B,MAAM,gBAAgB,CAAA;AACjF,OAAO,EAAU,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAEnE,MAAM,MAAM,cAAc,GAAG;IAC3B,iFAAiF;IACjF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,uFAAuF;IACvF,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAA;IACvB,0FAA0F;IAC1F,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC9D,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAA;IACjC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAA;IACtB,gEAAgE;IAChE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,0CAA0C;IAC1C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAC/B,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,SAAS,OAAO,KAAG,SAA4C,CAAA;AAkB5F;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACxB,KAAK,MAAM,EACX,SAAS,cAAc,KACtB,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAsEhD,CAAA"}
|
package/dist/connect.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { readWalletAddress } from "./address.js";
|
|
3
|
+
import { describeApiError, isCip30Api, readApiError, REFUSED } from "./cip30.js";
|
|
4
|
+
import { findWallet, injectedUnder } from "./discovery.js";
|
|
5
|
+
import { refuse } from "./wallet-error.js";
|
|
6
|
+
/**
|
|
7
|
+
* A CIP-19 address separates mainnet from testnet and no further, so this is
|
|
8
|
+
* every network id there is — preprod and preview are one value here. Telling
|
|
9
|
+
* them apart is exactly why a Slip states its network by name (`core/types.ts`).
|
|
10
|
+
*/
|
|
11
|
+
export const networkIdFor = (network) => (network === "mainnet" ? 1 : 0);
|
|
12
|
+
const networkNames = { 0: "a test network", 1: "mainnet" };
|
|
13
|
+
const call = (key, method, run) => Effect.tryPromise({
|
|
14
|
+
try: run,
|
|
15
|
+
catch: (cause) => {
|
|
16
|
+
const cip30 = readApiError(cause);
|
|
17
|
+
return refuse("Unreadable", key, `${method} failed: ${cip30 === undefined ? String(cause) : describeApiError(cip30)}`, cip30);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
/**
|
|
21
|
+
* Connects, or says why not. The network check happens here rather than in a
|
|
22
|
+
* component because it decides whether there is a connection at all: a wallet
|
|
23
|
+
* on another chain cannot sign this Slip's transaction, and letting the flow
|
|
24
|
+
* continue only moves the failure to where it costs a person more.
|
|
25
|
+
*/
|
|
26
|
+
export const connectWallet = (key, options) => Effect.gen(function* () {
|
|
27
|
+
const host = options.host ?? globalThis;
|
|
28
|
+
const wallet = findWallet(key, host);
|
|
29
|
+
if (wallet === undefined) {
|
|
30
|
+
return yield* Effect.fail(injectedUnder(key, host) === undefined
|
|
31
|
+
? refuse("NotInjected", key, "no wallet is installed under this name")
|
|
32
|
+
: refuse("NotCip30", key, "what is installed under this name does not implement CIP-30"));
|
|
33
|
+
}
|
|
34
|
+
const api = yield* Effect.tryPromise({
|
|
35
|
+
try: () => wallet.provider.enable(options.extensions),
|
|
36
|
+
catch: (cause) => {
|
|
37
|
+
const cip30 = readApiError(cause);
|
|
38
|
+
if (cip30?.code === REFUSED) {
|
|
39
|
+
return refuse("Refused", key, "the connection was declined in the wallet", cip30);
|
|
40
|
+
}
|
|
41
|
+
const detail = cip30 === undefined ? String(cause) : describeApiError(cip30);
|
|
42
|
+
return refuse("EnableFailed", key, `the wallet could not be connected: ${detail}`, cip30);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
// `enable()` is typed to return the API and is under no obligation to.
|
|
46
|
+
if (!isCip30Api(api)) {
|
|
47
|
+
return yield* Effect.fail(refuse("NotCip30", key, "the wallet connected without returning a CIP-30 API"));
|
|
48
|
+
}
|
|
49
|
+
const reported = yield* call(key, "getNetworkId", () => api.getNetworkId());
|
|
50
|
+
if (reported !== 0 && reported !== 1) {
|
|
51
|
+
return yield* Effect.fail(refuse("Unreadable", key, `getNetworkId answered ${String(reported)}`));
|
|
52
|
+
}
|
|
53
|
+
const networkId = reported === 1 ? 1 : 0;
|
|
54
|
+
const hex = yield* call(key, "getChangeAddress", () => api.getChangeAddress());
|
|
55
|
+
const address = yield* readWalletAddress(hex).pipe(Effect.mapError((detail) => refuse("Unreadable", key, `getChangeAddress answered ${detail}`)));
|
|
56
|
+
// Two answers about one wallet. A wallet that gives both cannot be taken at
|
|
57
|
+
// either word, and the disagreement is not the person's to resolve.
|
|
58
|
+
if (address.networkId !== networkId) {
|
|
59
|
+
return yield* Effect.fail(refuse("Unreadable", key, `the wallet reports ${networkNames[networkId]} and its change address is on ${networkNames[address.networkId]}`));
|
|
60
|
+
}
|
|
61
|
+
const expected = networkIdFor(options.network);
|
|
62
|
+
if (networkId !== expected) {
|
|
63
|
+
return yield* Effect.fail(refuse("WrongNetwork", key, `this Slip is on ${options.network} and the wallet is on ${networkNames[networkId]}`));
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
wallet,
|
|
67
|
+
api,
|
|
68
|
+
network: options.network,
|
|
69
|
+
networkId,
|
|
70
|
+
changeAddress: address.bech32
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
//# sourceMappingURL=connect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What is injected at `window.cardano`, read on demand. Nothing here touches a
|
|
3
|
+
* browser global at module scope: this SDK is imported by server-rendered pages
|
|
4
|
+
* we do not control, and a module that reads `window` while loading breaks them
|
|
5
|
+
* before any of it runs (ADR-0004).
|
|
6
|
+
*/
|
|
7
|
+
import { type Cip30Provider } from "./cip30.js";
|
|
8
|
+
export type DiscoveredWallet = {
|
|
9
|
+
/** The `window.cardano` key. What `connectWallet` is asked for. */
|
|
10
|
+
readonly key: string;
|
|
11
|
+
readonly name: string;
|
|
12
|
+
readonly icon: string | undefined;
|
|
13
|
+
readonly apiVersion: string;
|
|
14
|
+
/** CIP numbers the provider says it supports, before `enable()` negotiates any of them. */
|
|
15
|
+
readonly extensions: ReadonlyArray<number>;
|
|
16
|
+
/** Present only for a wallet in the registry. */
|
|
17
|
+
readonly install: string | undefined;
|
|
18
|
+
readonly provider: Cip30Provider;
|
|
19
|
+
};
|
|
20
|
+
/** Anything with a `cardano` namespace: a `Window`, or a stand-in in a test. */
|
|
21
|
+
export type WalletHost = {
|
|
22
|
+
readonly cardano?: unknown;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Every CIP-30 provider in the namespace, by display name. Returns an empty
|
|
26
|
+
* list where there is no namespace at all — a page with no wallet and a page
|
|
27
|
+
* rendered on a server are the same case to a caller, and neither is an error.
|
|
28
|
+
*/
|
|
29
|
+
export declare const discoverWallets: (host?: unknown) => ReadonlyArray<DiscoveredWallet>;
|
|
30
|
+
/**
|
|
31
|
+
* Whatever sits under the key, connector or not. Lets a caller separate a
|
|
32
|
+
* wallet that is not installed from one that is and does not speak CIP-30.
|
|
33
|
+
*/
|
|
34
|
+
export declare const injectedUnder: (key: string, host?: unknown) => unknown;
|
|
35
|
+
/** The provider under one key, or `undefined` where nothing usable is there. */
|
|
36
|
+
export declare const findWallet: (key: string, host?: unknown) => DiscoveredWallet | undefined;
|
|
37
|
+
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,KAAK,aAAa,EAAmB,MAAM,YAAY,CAAA;AAGhE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,mEAAmE;IACnE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,2FAA2F;IAC3F,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC1C,iDAAiD;IACjD,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAA;CACjC,CAAA;AAED,gFAAgF;AAChF,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAA;AA6BvD;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,OAAM,OAAoB,KAAG,aAAa,CAAC,gBAAgB,CAoB1F,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,KAAK,MAAM,EAAE,OAAM,OAAoB,KAAG,OAAmC,CAAA;AAE3G,gFAAgF;AAChF,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,EAAE,OAAM,OAAoB,KAAG,gBAAgB,GAAG,SAKvF,CAAA"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What is injected at `window.cardano`, read on demand. Nothing here touches a
|
|
3
|
+
* browser global at module scope: this SDK is imported by server-rendered pages
|
|
4
|
+
* we do not control, and a module that reads `window` while loading breaks them
|
|
5
|
+
* before any of it runs (ADR-0004).
|
|
6
|
+
*/
|
|
7
|
+
import { isCip30Provider } from "./cip30.js";
|
|
8
|
+
import { knownWallet } from "./registry.js";
|
|
9
|
+
const namespaceOf = (host) => {
|
|
10
|
+
if (typeof host !== "object" || host === null)
|
|
11
|
+
return undefined;
|
|
12
|
+
const cardano = host.cardano;
|
|
13
|
+
if (typeof cardano !== "object" || cardano === null)
|
|
14
|
+
return undefined;
|
|
15
|
+
return cardano;
|
|
16
|
+
};
|
|
17
|
+
const extensionsOf = (provider) => (provider.supportedExtensions ?? [])
|
|
18
|
+
.filter((extension) => typeof extension?.cip === "number")
|
|
19
|
+
.map((extension) => extension.cip);
|
|
20
|
+
const describe = (key, provider) => {
|
|
21
|
+
const known = knownWallet(key);
|
|
22
|
+
return {
|
|
23
|
+
key,
|
|
24
|
+
// The registry wins over the injected name so one extension reads the same
|
|
25
|
+
// way in every list; an unknown wallet still gets to name itself.
|
|
26
|
+
name: known?.name ?? (provider.name === "" ? key : provider.name),
|
|
27
|
+
icon: typeof provider.icon === "string" && provider.icon !== "" ? provider.icon : undefined,
|
|
28
|
+
apiVersion: provider.apiVersion,
|
|
29
|
+
extensions: extensionsOf(provider),
|
|
30
|
+
install: known?.install,
|
|
31
|
+
provider
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Every CIP-30 provider in the namespace, by display name. Returns an empty
|
|
36
|
+
* list where there is no namespace at all — a page with no wallet and a page
|
|
37
|
+
* rendered on a server are the same case to a caller, and neither is an error.
|
|
38
|
+
*/
|
|
39
|
+
export const discoverWallets = (host = globalThis) => {
|
|
40
|
+
const namespace = namespaceOf(host);
|
|
41
|
+
if (namespace === undefined)
|
|
42
|
+
return [];
|
|
43
|
+
const found = new Map();
|
|
44
|
+
for (const key of Object.keys(namespace)) {
|
|
45
|
+
const provider = namespace[key];
|
|
46
|
+
if (isCip30Provider(provider))
|
|
47
|
+
found.set(key, describe(key, provider));
|
|
48
|
+
}
|
|
49
|
+
// An extension injecting two keys is one wallet: listing it twice asks the
|
|
50
|
+
// person to choose between a wallet and itself.
|
|
51
|
+
for (const key of [...found.keys()]) {
|
|
52
|
+
const alias = knownWallet(key)?.aliasOf;
|
|
53
|
+
if (alias !== undefined && found.has(alias))
|
|
54
|
+
found.delete(key);
|
|
55
|
+
}
|
|
56
|
+
return [...found.values()].sort((left, right) => left.name.localeCompare(right.name) || left.key.localeCompare(right.key));
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Whatever sits under the key, connector or not. Lets a caller separate a
|
|
60
|
+
* wallet that is not installed from one that is and does not speak CIP-30.
|
|
61
|
+
*/
|
|
62
|
+
export const injectedUnder = (key, host = globalThis) => namespaceOf(host)?.[key];
|
|
63
|
+
/** The provider under one key, or `undefined` where nothing usable is there. */
|
|
64
|
+
export const findWallet = (key, host = globalThis) => {
|
|
65
|
+
const namespace = namespaceOf(host);
|
|
66
|
+
if (namespace === undefined)
|
|
67
|
+
return undefined;
|
|
68
|
+
const provider = namespace[key];
|
|
69
|
+
return isCip30Provider(provider) ? describe(key, provider) : undefined;
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAsB,eAAe,EAAE,MAAM,YAAY,CAAA;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAkB3C,MAAM,WAAW,GAAG,CAAC,IAAa,EAAuC,EAAE;IACzE,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,SAAS,CAAA;IAC/D,MAAM,OAAO,GAAI,IAAgC,CAAC,OAAO,CAAA;IACzD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,SAAS,CAAA;IACrE,OAAO,OAAkC,CAAA;AAC3C,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,CAAC,QAAuB,EAAyB,EAAE,CACtE,CAAC,QAAQ,CAAC,mBAAmB,IAAI,EAAE,CAAC;KACjC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,SAAS,EAAE,GAAG,KAAK,QAAQ,CAAC;KACzD,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;AAEtC,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,QAAuB,EAAoB,EAAE;IAC1E,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;IAC9B,OAAO;QACL,GAAG;QACH,2EAA2E;QAC3E,kEAAkE;QAClE,IAAI,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QACjE,IAAI,EAAE,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QAC3F,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,UAAU,EAAE,YAAY,CAAC,QAAQ,CAAC;QAClC,OAAO,EAAE,KAAK,EAAE,OAAO;QACvB,QAAQ;KACT,CAAA;AACH,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAgB,UAAU,EAAmC,EAAE;IAC7F,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,CAAA;IACnC,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,EAAE,CAAA;IAEtC,MAAM,KAAK,GAAG,IAAI,GAAG,EAA4B,CAAA;IACjD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAA;QAC/B,IAAI,eAAe,CAAC,QAAQ,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAA;IACxE,CAAC;IAED,2EAA2E;IAC3E,gDAAgD;IAChD,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,OAAO,CAAA;QACvC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAChE,CAAC;IAED,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAC7B,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAC1F,CAAA;AACH,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAW,EAAE,OAAgB,UAAU,EAAW,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;AAE3G,gFAAgF;AAChF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,OAAgB,UAAU,EAAgC,EAAE;IAClG,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,CAAA;IACnC,IAAI,SAAS,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC7C,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAA;IAC/B,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AACxE,CAAC,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The public entry point of `@cardano-slips/flow`. The `exports` map exposes
|
|
3
3
|
* this module and nothing else, so moving a file is never a breaking change.
|
|
4
|
-
*
|
|
5
|
-
* Two properties hold as the rest of the package arrives. It refuses but does
|
|
6
|
-
* not decide — the comparison is `verifier`'s, and a mismatch renders as a
|
|
7
|
-
* block with no override path to write. And it does not own the page it is
|
|
8
|
-
* dropped into: no fixed positioning, no assumptions about the document, and
|
|
9
|
-
* colours only from the custom properties in `tokens.css`.
|
|
10
4
|
*/
|
|
11
|
-
export {};
|
|
5
|
+
export type { NetworkId, WalletAddress } from "./address.js";
|
|
6
|
+
export { readWalletAddress } from "./address.js";
|
|
7
|
+
export type { CborHex, Cip30Api, Cip30ApiError, Cip30Provider, Paginate, SignedData } from "./cip30.js";
|
|
8
|
+
export { apiErrorNames, describeApiError, isCip30Api, isCip30Provider, readApiError, REFUSED } from "./cip30.js";
|
|
9
|
+
export type { ConnectedWallet, ConnectOptions } from "./connect.js";
|
|
10
|
+
export { connectWallet, networkIdFor } from "./connect.js";
|
|
11
|
+
export type { DiscoveredWallet, WalletHost } from "./discovery.js";
|
|
12
|
+
export { discoverWallets, findWallet, injectedUnder } from "./discovery.js";
|
|
13
|
+
export type { KnownWallet } from "./registry.js";
|
|
14
|
+
export { knownWallet, knownWallets } from "./registry.js";
|
|
15
|
+
export type { ConnectRefusal } from "./wallet-error.js";
|
|
16
|
+
export { connectRefusals, slipErrorCodeFor, WalletConnectError } from "./wallet-error.js";
|
|
12
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvG,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAChH,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AACnE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC1D,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAClE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC3E,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACzD,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export { readWalletAddress } from "./address.js";
|
|
2
|
+
export { apiErrorNames, describeApiError, isCip30Api, isCip30Provider, readApiError, REFUSED } from "./cip30.js";
|
|
3
|
+
export { connectWallet, networkIdFor } from "./connect.js";
|
|
4
|
+
export { discoverWallets, findWallet, injectedUnder } from "./discovery.js";
|
|
5
|
+
export { knownWallet, knownWallets } from "./registry.js";
|
|
6
|
+
export { connectRefusals, slipErrorCodeFor, WalletConnectError } from "./wallet-error.js";
|
|
2
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAEhD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEhH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE1D,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAE3E,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAEzD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Display metadata for the wallets we know by name. Ours to maintain — the one
|
|
3
|
+
* cost ADR-0004 accepted — and deliberately thin: a key an entry does not cover
|
|
4
|
+
* still connects, using the name and icon the extension injects.
|
|
5
|
+
*
|
|
6
|
+
* `install` is the wallet's own home page rather than a store listing, because
|
|
7
|
+
* a store listing is per browser and goes stale on its own schedule.
|
|
8
|
+
*/
|
|
9
|
+
export type KnownWallet = {
|
|
10
|
+
readonly key: string;
|
|
11
|
+
readonly name: string;
|
|
12
|
+
readonly install: string;
|
|
13
|
+
/** A second key the same extension injects. Hidden while the primary is present. */
|
|
14
|
+
readonly aliasOf?: string;
|
|
15
|
+
};
|
|
16
|
+
export declare const knownWallets: ReadonlyArray<KnownWallet>;
|
|
17
|
+
export declare const knownWallet: (key: string) => KnownWallet | undefined;
|
|
18
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,oFAAoF;IACpF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAC1B,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,aAAa,CAAC,WAAW,CAWnD,CAAA;AAID,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,WAAW,GAAG,SAA2B,CAAA"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const knownWallets = [
|
|
2
|
+
{ key: "lace", name: "Lace", install: "https://www.lace.io" },
|
|
3
|
+
{ key: "eternl", name: "Eternl", install: "https://eternl.io" },
|
|
4
|
+
{ key: "ccvault", name: "Eternl", install: "https://eternl.io", aliasOf: "eternl" },
|
|
5
|
+
{ key: "vespr", name: "VESPR", install: "https://vespr.xyz" },
|
|
6
|
+
{ key: "typhoncip30", name: "Typhon", install: "https://typhonwallet.io" },
|
|
7
|
+
{ key: "nami", name: "Nami", install: "https://www.namiwallet.io" },
|
|
8
|
+
{ key: "begin", name: "Begin", install: "https://begin.is" },
|
|
9
|
+
{ key: "nufi", name: "NuFi", install: "https://nu.fi" },
|
|
10
|
+
{ key: "gerowallet", name: "GeroWallet", install: "https://gerowallet.io" },
|
|
11
|
+
{ key: "yoroi", name: "Yoroi", install: "https://yoroi-wallet.com" }
|
|
12
|
+
];
|
|
13
|
+
const byKey = new Map(knownWallets.map((wallet) => [wallet.key, wallet]));
|
|
14
|
+
export const knownWallet = (key) => byKey.get(key);
|
|
15
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAgBA,MAAM,CAAC,MAAM,YAAY,GAA+B;IACtD,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,EAAE;IAC7D,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,mBAAmB,EAAE;IAC/D,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,QAAQ,EAAE;IACnF,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE;IAC7D,EAAE,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,yBAAyB,EAAE;IAC1E,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,2BAA2B,EAAE;IACnE,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE;IAC5D,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE;IACvD,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,uBAAuB,EAAE;IAC3E,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,0BAA0B,EAAE;CACrE,CAAA;AAED,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;AAEzE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAW,EAA2B,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA"}
|