@reclack/walletkit 0.0.0-stage → 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.
Files changed (170) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +341 -2
  3. package/assets/backpack.webp +0 -0
  4. package/assets/berasig.webp +0 -0
  5. package/assets/bestwallet.webp +0 -0
  6. package/assets/bifrostwallet.webp +0 -0
  7. package/assets/binance.webp +0 -0
  8. package/assets/bitcoincom.webp +0 -0
  9. package/assets/bitget.webp +0 -0
  10. package/assets/bitpay.webp +0 -0
  11. package/assets/bitski.webp +0 -0
  12. package/assets/bitverse.webp +0 -0
  13. package/assets/blockchaincom.webp +0 -0
  14. package/assets/brave.webp +0 -0
  15. package/assets/bybit.webp +0 -0
  16. package/assets/clv.webp +0 -0
  17. package/assets/coin98.webp +0 -0
  18. package/assets/coinbase.webp +0 -0
  19. package/assets/compass.webp +0 -0
  20. package/assets/core.webp +0 -0
  21. package/assets/crypto_com.webp +0 -0
  22. package/assets/ctrl.webp +0 -0
  23. package/assets/dawn.webp +0 -0
  24. package/assets/desig.webp +0 -0
  25. package/assets/enkrypt.webp +0 -0
  26. package/assets/exodus.webp +0 -0
  27. package/assets/foxwallet.webp +0 -0
  28. package/assets/frame.webp +0 -0
  29. package/assets/frontier.webp +0 -0
  30. package/assets/gate.webp +0 -0
  31. package/assets/gemini.webp +0 -0
  32. package/assets/imtoken.webp +0 -0
  33. package/assets/iopay.webp +0 -0
  34. package/assets/kaia.webp +0 -0
  35. package/assets/kaikas.webp +0 -0
  36. package/assets/kraken.webp +0 -0
  37. package/assets/kresuswallet.webp +0 -0
  38. package/assets/ledger.webp +0 -0
  39. package/assets/magiceden.webp +0 -0
  40. package/assets/meco.webp +0 -0
  41. package/assets/metamask.webp +0 -0
  42. package/assets/mew.webp +0 -0
  43. package/assets/nest.webp +0 -0
  44. package/assets/nova.webp +0 -0
  45. package/assets/okto.webp +0 -0
  46. package/assets/okx.webp +0 -0
  47. package/assets/oneinch.webp +0 -0
  48. package/assets/onekey.webp +0 -0
  49. package/assets/phantom.webp +0 -0
  50. package/assets/rabby.webp +0 -0
  51. package/assets/rainbow.webp +0 -0
  52. package/assets/ramper.webp +0 -0
  53. package/assets/ready.webp +0 -0
  54. package/assets/ronin.webp +0 -0
  55. package/assets/safe.webp +0 -0
  56. package/assets/safepal.webp +0 -0
  57. package/assets/solflare.webp +0 -0
  58. package/assets/subwallet.webp +0 -0
  59. package/assets/taho.webp +0 -0
  60. package/assets/talisman.webp +0 -0
  61. package/assets/tokenary.webp +0 -0
  62. package/assets/tokenpocket.webp +0 -0
  63. package/assets/trust-wallet.webp +0 -0
  64. package/assets/uniswap.webp +0 -0
  65. package/assets/universalprofiles.webp +0 -0
  66. package/assets/valora.webp +0 -0
  67. package/assets/wigwam.webp +0 -0
  68. package/assets/xportal.webp +0 -0
  69. package/assets/zeal.webp +0 -0
  70. package/assets/zerion.webp +0 -0
  71. package/custom-elements.json +207 -0
  72. package/dist/abi.d.ts +21 -0
  73. package/dist/abi.d.ts.map +1 -0
  74. package/dist/abi.js +50 -0
  75. package/dist/abi.js.map +1 -0
  76. package/dist/address.d.ts +15 -0
  77. package/dist/address.d.ts.map +1 -0
  78. package/dist/address.js +25 -0
  79. package/dist/address.js.map +1 -0
  80. package/dist/balance.d.ts +78 -0
  81. package/dist/balance.d.ts.map +1 -0
  82. package/dist/balance.js +146 -0
  83. package/dist/balance.js.map +1 -0
  84. package/dist/base58.d.ts +15 -0
  85. package/dist/base58.d.ts.map +1 -0
  86. package/dist/base58.js +52 -0
  87. package/dist/base58.js.map +1 -0
  88. package/dist/catalog-fetch.d.ts +18 -0
  89. package/dist/catalog-fetch.d.ts.map +1 -0
  90. package/dist/catalog-fetch.js +85 -0
  91. package/dist/catalog-fetch.js.map +1 -0
  92. package/dist/catalog.d.ts +57 -0
  93. package/dist/catalog.d.ts.map +1 -0
  94. package/dist/catalog.js +80 -0
  95. package/dist/catalog.js.map +1 -0
  96. package/dist/chains.d.ts +32 -0
  97. package/dist/chains.d.ts.map +1 -0
  98. package/dist/chains.js +103 -0
  99. package/dist/chains.js.map +1 -0
  100. package/dist/config.d.ts +40 -0
  101. package/dist/config.d.ts.map +1 -0
  102. package/dist/config.js +44 -0
  103. package/dist/config.js.map +1 -0
  104. package/dist/deep-links.d.ts +22 -0
  105. package/dist/deep-links.d.ts.map +1 -0
  106. package/dist/deep-links.js +201 -0
  107. package/dist/deep-links.js.map +1 -0
  108. package/dist/device.d.ts +23 -0
  109. package/dist/device.d.ts.map +1 -0
  110. package/dist/device.js +59 -0
  111. package/dist/device.js.map +1 -0
  112. package/dist/element/attributes.d.ts +48 -0
  113. package/dist/element/element.d.ts +92 -0
  114. package/dist/element/index.d.ts +4 -0
  115. package/dist/element/props.d.ts +67 -0
  116. package/dist/element/ui/app.d.ts +22 -0
  117. package/dist/element/ui/assets.d.ts +7 -0
  118. package/dist/element/ui/qr.d.ts +16 -0
  119. package/dist/element/ui/use-handheld.d.ts +8 -0
  120. package/dist/element/ui/wallet-connect-panel.d.ts +26 -0
  121. package/dist/element/ui/wallet-dialog.d.ts +37 -0
  122. package/dist/element/ui/wallet-list.d.ts +26 -0
  123. package/dist/element/ui/wallet-mark.d.ts +15 -0
  124. package/dist/element.js +2079 -0
  125. package/dist/errors.d.ts +34 -0
  126. package/dist/errors.d.ts.map +1 -0
  127. package/dist/errors.js +64 -0
  128. package/dist/errors.js.map +1 -0
  129. package/dist/evm.d.ts +49 -0
  130. package/dist/evm.d.ts.map +1 -0
  131. package/dist/evm.js +217 -0
  132. package/dist/evm.js.map +1 -0
  133. package/dist/icons.d.ts +22 -0
  134. package/dist/icons.d.ts.map +1 -0
  135. package/dist/icons.js +98 -0
  136. package/dist/icons.js.map +1 -0
  137. package/dist/index.d.ts +39 -0
  138. package/dist/index.d.ts.map +1 -0
  139. package/dist/index.js +43 -0
  140. package/dist/index.js.map +1 -0
  141. package/dist/intent.d.ts +60 -0
  142. package/dist/intent.d.ts.map +1 -0
  143. package/dist/intent.js +2 -0
  144. package/dist/intent.js.map +1 -0
  145. package/dist/kit.d.ts +124 -0
  146. package/dist/kit.d.ts.map +1 -0
  147. package/dist/kit.js +362 -0
  148. package/dist/kit.js.map +1 -0
  149. package/dist/svm.d.ts +45 -0
  150. package/dist/svm.d.ts.map +1 -0
  151. package/dist/svm.js +201 -0
  152. package/dist/svm.js.map +1 -0
  153. package/dist/theme.d.ts +101 -0
  154. package/dist/theme.d.ts.map +1 -0
  155. package/dist/theme.js +217 -0
  156. package/dist/theme.js.map +1 -0
  157. package/dist/types.d.ts +144 -0
  158. package/dist/types.d.ts.map +1 -0
  159. package/dist/types.js +2 -0
  160. package/dist/types.js.map +1 -0
  161. package/dist/wallet-standard.d.ts +77 -0
  162. package/dist/wallet-standard.d.ts.map +1 -0
  163. package/dist/wallet-standard.js +89 -0
  164. package/dist/wallet-standard.js.map +1 -0
  165. package/dist/walletconnect.d.ts +74 -0
  166. package/dist/walletconnect.d.ts.map +1 -0
  167. package/dist/walletconnect.js +133 -0
  168. package/dist/walletconnect.js.map +1 -0
  169. package/package.json +71 -3
  170. package/vscode.html-custom-data.json +55 -0
@@ -0,0 +1,207 @@
1
+ {
2
+ "schemaVersion": "2.1.0",
3
+ "readme": "README.md",
4
+ "modules": [
5
+ {
6
+ "kind": "javascript-module",
7
+ "path": "dist/element.js",
8
+ "declarations": [
9
+ {
10
+ "kind": "class",
11
+ "name": "ReclackConnectElement",
12
+ "tagName": "reclack-connect",
13
+ "customElement": true,
14
+ "description": "Connect a wallet, read an address, read a balance.",
15
+ "attributes": [
16
+ {
17
+ "name": "variant",
18
+ "type": {
19
+ "text": "'inline' | 'modal'"
20
+ },
21
+ "description": "Where the picker sits: a list on the page, or the whole picker over it."
22
+ },
23
+ {
24
+ "name": "family",
25
+ "type": {
26
+ "text": "'evm' | 'svm'"
27
+ },
28
+ "description": "Restricts the list to one chain family. Both when absent."
29
+ },
30
+ {
31
+ "name": "chain-id",
32
+ "type": {
33
+ "text": "number"
34
+ },
35
+ "description": "The EVM chain the wallet must end up on. No switch is forced without it."
36
+ },
37
+ {
38
+ "name": "intent",
39
+ "type": {
40
+ "text": "string"
41
+ },
42
+ "description": "Comma separated: address, balance."
43
+ },
44
+ {
45
+ "name": "keep-alive",
46
+ "type": {
47
+ "text": "boolean"
48
+ },
49
+ "description": "Hold the connection open afterwards, for a page that signs later."
50
+ },
51
+ {
52
+ "name": "theme-mode",
53
+ "type": {
54
+ "text": "'light' | 'dark' | 'system'"
55
+ },
56
+ "description": "Light, dark, or whatever the reader\u2019s system says."
57
+ },
58
+ {
59
+ "name": "brand",
60
+ "type": {
61
+ "text": "string"
62
+ },
63
+ "description": "#rrggbb. Anything else is ignored and the default stands."
64
+ },
65
+ {
66
+ "name": "radius",
67
+ "type": {
68
+ "text": "string"
69
+ },
70
+ "description": "Corner radius, as a CSS length."
71
+ },
72
+ {
73
+ "name": "font",
74
+ "type": {
75
+ "text": "string"
76
+ },
77
+ "description": "The host\u2019s type, so the picker does not arrive in a different face."
78
+ },
79
+ {
80
+ "name": "asset-base",
81
+ "type": {
82
+ "text": "string"
83
+ },
84
+ "description": "Where the host serves this package's assets/ directory from."
85
+ },
86
+ {
87
+ "name": "api-url",
88
+ "type": {
89
+ "text": "string"
90
+ },
91
+ "description": "A different Reclack to read the wallet catalogue from, such as a sandbox."
92
+ }
93
+ ],
94
+ "members": [
95
+ {
96
+ "kind": "field",
97
+ "name": "kit",
98
+ "type": {
99
+ "text": "WalletKit"
100
+ },
101
+ "description": "A kit to share rather than one this element would make for itself."
102
+ },
103
+ {
104
+ "kind": "field",
105
+ "name": "request",
106
+ "type": {
107
+ "text": "ConnectRequest"
108
+ },
109
+ "description": "The whole request, for an intent carrying assets."
110
+ },
111
+ {
112
+ "kind": "field",
113
+ "name": "theme",
114
+ "type": {
115
+ "text": "WalletKitTheme"
116
+ },
117
+ "description": "The whole theme, for per-mode overrides."
118
+ }
119
+ ],
120
+ "events": [
121
+ {
122
+ "name": "connect",
123
+ "type": {
124
+ "text": "CustomEvent<ConnectResult>"
125
+ },
126
+ "description": "A wallet was connected and the intent resolved."
127
+ },
128
+ {
129
+ "name": "cancel",
130
+ "type": {
131
+ "text": "CustomEvent"
132
+ },
133
+ "description": "The picker was closed without connecting."
134
+ },
135
+ {
136
+ "name": "connect-error",
137
+ "type": {
138
+ "text": "CustomEvent<{ message: string }>"
139
+ },
140
+ "description": "Something refused. Named connect-error because every element already has an error event for a resource that failed to load."
141
+ }
142
+ ],
143
+ "cssProperties": [
144
+ {
145
+ "name": "--rkw-surface",
146
+ "description": "The panel itself."
147
+ },
148
+ {
149
+ "name": "--rkw-ground",
150
+ "description": "Behind the panel."
151
+ },
152
+ {
153
+ "name": "--rkw-plate",
154
+ "description": "Rows and plates inside it."
155
+ },
156
+ {
157
+ "name": "--rkw-ink",
158
+ "description": "Primary text."
159
+ },
160
+ {
161
+ "name": "--rkw-ink-muted",
162
+ "description": "Secondary text."
163
+ },
164
+ {
165
+ "name": "--rkw-line",
166
+ "description": "Hairlines and borders."
167
+ },
168
+ {
169
+ "name": "--rkw-brand",
170
+ "description": "The primary action and the focus ring."
171
+ },
172
+ {
173
+ "name": "--rkw-brand-ink",
174
+ "description": "Text on the brand colour. Computed when not set."
175
+ },
176
+ {
177
+ "name": "--rkw-danger",
178
+ "description": "A refusal."
179
+ },
180
+ {
181
+ "name": "--rkw-ok",
182
+ "description": "A success."
183
+ },
184
+ {
185
+ "name": "--rkw-radius",
186
+ "description": "Corner radius."
187
+ },
188
+ {
189
+ "name": "--rkw-font",
190
+ "description": "Type face."
191
+ }
192
+ ]
193
+ }
194
+ ],
195
+ "exports": [
196
+ {
197
+ "kind": "custom-element-definition",
198
+ "name": "reclack-connect",
199
+ "declaration": {
200
+ "name": "ReclackConnectElement",
201
+ "module": "dist/element.js"
202
+ }
203
+ }
204
+ ]
205
+ }
206
+ ]
207
+ }
package/dist/abi.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The smallest ABI encoder that can authorize a subscription.
3
+ *
4
+ * No wallet SDK and no keccak implementation ship in this bundle. Every call
5
+ * this page makes has a fixed signature, so the four-byte selectors are
6
+ * constants: computed once with `cast sig` and pinned below, and every
7
+ * argument is a static 32-byte word. That makes the encoder a few lines of
8
+ * string work instead of a dependency on a checkout page that handles money.
9
+ *
10
+ * Regenerate a selector with:
11
+ * cast sig "approve(address,uint256)"
12
+ * The unit test in abi.test.ts asserts these against the same signatures.
13
+ */
14
+ /** Left-pads a hex value to one 32-byte ABI word. */
15
+ export declare function word(value: bigint | string): string;
16
+ /** Encodes an address as a left-padded word, rejecting anything malformed. */
17
+ export declare function addressWord(address: string): string;
18
+ /** A bytes32 value, right-padded: the one argument that is not left-aligned. */
19
+ export declare function bytes32(hex: string): string;
20
+ /** Concatenates a selector and its already-encoded words into calldata. */
21
+ export declare function calldata(selector: string, words: string[]): string;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abi.d.ts","sourceRoot":"","sources":["../src/abi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,qDAAqD;AACrD,wBAAgB,IAAI,CAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAcpD;AAED,8EAA8E;AAC9E,wBAAgB,WAAW,CAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAKpD;AAED,gFAAgF;AAChF,wBAAgB,OAAO,CAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAM5C;AAED,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAEnE"}
package/dist/abi.js ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * The smallest ABI encoder that can authorize a subscription.
3
+ *
4
+ * No wallet SDK and no keccak implementation ship in this bundle. Every call
5
+ * this page makes has a fixed signature, so the four-byte selectors are
6
+ * constants: computed once with `cast sig` and pinned below, and every
7
+ * argument is a static 32-byte word. That makes the encoder a few lines of
8
+ * string work instead of a dependency on a checkout page that handles money.
9
+ *
10
+ * Regenerate a selector with:
11
+ * cast sig "approve(address,uint256)"
12
+ * The unit test in abi.test.ts asserts these against the same signatures.
13
+ */
14
+ /** Left-pads a hex value to one 32-byte ABI word. */
15
+ export function word(value) {
16
+ let hex;
17
+ if (typeof value === 'bigint') {
18
+ if (value < 0n) {
19
+ throw new Error('negative values are not encodable here');
20
+ }
21
+ hex = value.toString(16);
22
+ }
23
+ else {
24
+ hex = value.toLowerCase().replace(/^0x/, '');
25
+ }
26
+ if (hex.length > 64) {
27
+ throw new Error('value does not fit in a 32-byte word');
28
+ }
29
+ return hex.padStart(64, '0');
30
+ }
31
+ /** Encodes an address as a left-padded word, rejecting anything malformed. */
32
+ export function addressWord(address) {
33
+ if (!/^0x[0-9a-fA-F]{40}$/.test(address)) {
34
+ throw new Error('invalid address');
35
+ }
36
+ return word(address);
37
+ }
38
+ /** A bytes32 value, right-padded: the one argument that is not left-aligned. */
39
+ export function bytes32(hex) {
40
+ const raw = hex.toLowerCase().replace(/^0x/, '');
41
+ if (raw.length > 64 || /[^0-9a-f]/.test(raw)) {
42
+ throw new Error('invalid bytes32');
43
+ }
44
+ return raw.padEnd(64, '0');
45
+ }
46
+ /** Concatenates a selector and its already-encoded words into calldata. */
47
+ export function calldata(selector, words) {
48
+ return selector + words.join('');
49
+ }
50
+ //# sourceMappingURL=abi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abi.js","sourceRoot":"","sources":["../src/abi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,qDAAqD;AACrD,MAAM,UAAU,IAAI,CAAE,KAAsB;IAC3C,IAAI,GAAW,CAAA;IACf,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;QAC1D,CAAC;QACD,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IACzB,CAAC;SAAM,CAAC;QACP,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAC7C,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAA;IACxD,CAAC;IACD,OAAO,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;AAC7B,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,WAAW,CAAE,OAAe;IAC3C,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACnC,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,CAAA;AACrB,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,OAAO,CAAE,GAAW;IACnC,MAAM,GAAG,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAChD,IAAI,GAAG,CAAC,MAAM,GAAG,EAAE,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACnC,CAAC;IACD,OAAO,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;AAC3B,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,QAAQ,CAAE,QAAgB,EAAE,KAAe;IAC1D,OAAO,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AACjC,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * An address, shortened the way addresses are shortened.
3
+ *
4
+ * Head and tail, not a card-style mask: an address is not a secret to be
5
+ * redacted, it is a public identifier that is merely too long for the place
6
+ * it has to fit. Both ends carry meaning: the prefix says which chain family
7
+ * it belongs to, and the tail is what somebody quotes when asking about a
8
+ * payment.
9
+ *
10
+ * One function for every surface, because the same wallet should read the
11
+ * same wherever it appears. This used to be written out separately in the
12
+ * checkout and in the dashboard, each with a comment saying it matched the
13
+ * other.
14
+ */
15
+ export declare function shortAddress(address: string | undefined): string | undefined;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../src/address.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAE,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAS7E"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * An address, shortened the way addresses are shortened.
3
+ *
4
+ * Head and tail, not a card-style mask: an address is not a secret to be
5
+ * redacted, it is a public identifier that is merely too long for the place
6
+ * it has to fit. Both ends carry meaning: the prefix says which chain family
7
+ * it belongs to, and the tail is what somebody quotes when asking about a
8
+ * payment.
9
+ *
10
+ * One function for every surface, because the same wallet should read the
11
+ * same wherever it appears. This used to be written out separately in the
12
+ * checkout and in the dashboard, each with a comment saying it matched the
13
+ * other.
14
+ */
15
+ export function shortAddress(address) {
16
+ const value = address?.trim();
17
+ if (!value) {
18
+ return undefined;
19
+ }
20
+ if (value.length < 12) {
21
+ return value;
22
+ }
23
+ return `${value.slice(0, 6)}…${value.slice(-4)}`;
24
+ }
25
+ //# sourceMappingURL=address.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.js","sourceRoot":"","sources":["../src/address.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,YAAY,CAAE,OAA2B;IACxD,MAAM,KAAK,GAAG,OAAO,EAAE,IAAI,EAAE,CAAA;IAC7B,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,OAAO,SAAS,CAAA;IACjB,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACvB,OAAO,KAAK,CAAA;IACb,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AACjD,CAAC"}
@@ -0,0 +1,78 @@
1
+ import type { Eip1193Provider } from './types.js';
2
+ /**
3
+ * What a balance is a balance of.
4
+ *
5
+ * Omitting the contract means the chain's own coin, which is a real question
6
+ * and not an edge case: the authorization path is relayed and needs no gas,
7
+ * but the approve and transfer paths do, and "no ETH" is the failure a token
8
+ * balance does not catch.
9
+ */
10
+ export type Asset = {
11
+ family: 'evm';
12
+ chainId: number;
13
+ /** ERC-20 contract. Absent for the chain's native coin. */
14
+ token?: string;
15
+ decimals?: number;
16
+ symbol?: string;
17
+ } | {
18
+ family: 'svm';
19
+ /** SPL mint. Absent for SOL itself. */
20
+ mint?: string;
21
+ decimals?: number;
22
+ symbol?: string;
23
+ };
24
+ /**
25
+ * An amount, in the asset's smallest unit.
26
+ *
27
+ * A bigint, never a number. Money does not survive a float: 0.1 + 0.2 is not
28
+ * 0.3 in binary, and a balance compared against a charge decides whether
29
+ * somebody is asked to sign something that cannot settle.
30
+ */
31
+ export interface Balance {
32
+ asset: Asset;
33
+ amount: bigint;
34
+ decimals: number;
35
+ symbol?: string;
36
+ }
37
+ /**
38
+ * Where a balance is read from, and the choice matters more than it looks.
39
+ *
40
+ * Through the connected wallet's own provider, the wallet has to be on that
41
+ * chain, so asking for a balance forces a network switch. Through an RPC
42
+ * endpoint it does not, and several chains can be read at once. So the RPC is
43
+ * the default for anything informational, and the provider is for the one
44
+ * case that needs it: the pre-flight immediately before signing, where the
45
+ * question is what this exact wallet can spend right now.
46
+ */
47
+ export type BalanceSource = {
48
+ provider: Eip1193Provider;
49
+ } | {
50
+ rpcUrl: string;
51
+ };
52
+ /** The payer's balance of one EVM asset. */
53
+ export declare function readEvmBalance(source: BalanceSource, asset: Extract<Asset, {
54
+ family: 'evm';
55
+ }>, owner: string): Promise<Balance>;
56
+ /**
57
+ * The payer's balance of one Solana asset.
58
+ *
59
+ * RPC only. Solana wallets sign; they do not answer questions about the
60
+ * chain, so there is no provider path here the way there is on EVM.
61
+ *
62
+ * Token accounts are listed by mint rather than deriving the associated
63
+ * account address, which would mean shipping a program-derived-address
64
+ * implementation to answer a question the node can answer directly. An owner
65
+ * may hold several accounts for one mint, so they are summed.
66
+ */
67
+ export declare function readSvmBalance(rpcUrl: string, asset: Extract<Asset, {
68
+ family: 'svm';
69
+ }>, owner: string): Promise<Balance>;
70
+ /**
71
+ * Formats an amount for display, without ever making it a float.
72
+ *
73
+ * String arithmetic on the integer, not a division: the whole reason the
74
+ * amount is a bigint is that the moment it becomes a Number it stops being
75
+ * exact, and a balance is shown next to a charge the payer is about to
76
+ * approve.
77
+ */
78
+ export declare function formatUnits(amount: bigint, decimals: number): string;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance.d.ts","sourceRoot":"","sources":["../src/balance.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD;;;;;;;GAOG;AACH,MAAM,MAAM,KAAK,GACd;IACD,MAAM,EAAE,KAAK,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;CACf,GACC;IACD,MAAM,EAAE,KAAK,CAAA;IACb,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAEF;;;;;;GAMG;AACH,MAAM,WAAW,OAAO;IACvB,KAAK,EAAE,KAAK,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,aAAa,GACtB;IAAE,QAAQ,EAAE,eAAe,CAAA;CAAE,GAC7B;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AA+ErB,4CAA4C;AAC5C,wBAAsB,cAAc,CACnC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE;IAAE,MAAM,EAAE,KAAK,CAAA;CAAE,CAAC,EACxC,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CA0BlB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CACnC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE;IAAE,MAAM,EAAE,KAAK,CAAA;CAAE,CAAC,EACxC,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CA+BlB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CASrE"}
@@ -0,0 +1,146 @@
1
+ import { addressWord, calldata } from './abi.js';
2
+ import { chainMetadata } from './chains.js';
3
+ // cast sig "balanceOf(address)"
4
+ const BALANCE_OF_SELECTOR = '0x70a08231';
5
+ // cast sig "decimals()"
6
+ const DECIMALS_SELECTOR = '0x313ce567';
7
+ /** Lamports per SOL, and the decimals every SOL balance is quoted in. */
8
+ const SOL_DECIMALS = 9;
9
+ function hexToBigInt(raw) {
10
+ return typeof raw === 'string' && raw !== '0x' ? BigInt(raw) : 0n;
11
+ }
12
+ /**
13
+ * One JSON-RPC call over HTTP.
14
+ *
15
+ * Hand-rolled rather than pulled from a client library, for the same reason
16
+ * the ABI encoder is: this package runs on pages that handle other people's
17
+ * money, and every dependency is code somebody else can change under us.
18
+ */
19
+ async function rpc(url, method, params) {
20
+ const response = await fetch(url, {
21
+ method: 'POST',
22
+ credentials: 'omit',
23
+ headers: { 'Content-Type': 'application/json' },
24
+ body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),
25
+ });
26
+ if (!response.ok) {
27
+ throw new Error(`RPC ${method} failed: ${response.status}`);
28
+ }
29
+ const body = (await response.json());
30
+ if (body.error) {
31
+ throw new Error(body.error.message ?? `RPC ${method} failed`);
32
+ }
33
+ return body.result;
34
+ }
35
+ /** An eth_call, through whichever source was given. */
36
+ async function call(source, to, data) {
37
+ const params = [{ to, data }, 'latest'];
38
+ return 'provider' in source
39
+ ? source.provider.request({ method: 'eth_call', params })
40
+ : rpc(source.rpcUrl, 'eth_call', params);
41
+ }
42
+ /**
43
+ * How many decimals the token quotes, asked of the token itself.
44
+ *
45
+ * Only when the caller did not say. A caller that knows should pass it: USDC
46
+ * is six everywhere it matters, and a round trip to find that out again is a
47
+ * round trip.
48
+ */
49
+ async function evmDecimals(source, token, given) {
50
+ if (typeof given === 'number') {
51
+ return given;
52
+ }
53
+ const raw = await call(source, token, calldata(DECIMALS_SELECTOR, []));
54
+ const value = Number(hexToBigInt(raw));
55
+ // A token that answers something absurd is a token this is not going to
56
+ // get right by guessing. Eighteen is the ERC-20 default.
57
+ return Number.isInteger(value) && value >= 0 && value <= 36 ? value : 18;
58
+ }
59
+ /** The payer's balance of one EVM asset. */
60
+ export async function readEvmBalance(source, asset, owner) {
61
+ if (!asset.token) {
62
+ const params = [owner, 'latest'];
63
+ const raw = 'provider' in source
64
+ ? await source.provider.request({ method: 'eth_getBalance', params })
65
+ : await rpc(source.rpcUrl, 'eth_getBalance', params);
66
+ const native = chainMetadata(asset.chainId)?.nativeCurrency;
67
+ return {
68
+ asset,
69
+ amount: hexToBigInt(raw),
70
+ decimals: asset.decimals ?? native?.decimals ?? 18,
71
+ symbol: asset.symbol ?? native?.symbol,
72
+ };
73
+ }
74
+ const data = calldata(BALANCE_OF_SELECTOR, [addressWord(owner)]);
75
+ const [raw, decimals] = await Promise.all([
76
+ call(source, asset.token, data),
77
+ evmDecimals(source, asset.token, asset.decimals),
78
+ ]);
79
+ return {
80
+ asset,
81
+ amount: hexToBigInt(raw),
82
+ decimals,
83
+ symbol: asset.symbol,
84
+ };
85
+ }
86
+ /**
87
+ * The payer's balance of one Solana asset.
88
+ *
89
+ * RPC only. Solana wallets sign; they do not answer questions about the
90
+ * chain, so there is no provider path here the way there is on EVM.
91
+ *
92
+ * Token accounts are listed by mint rather than deriving the associated
93
+ * account address, which would mean shipping a program-derived-address
94
+ * implementation to answer a question the node can answer directly. An owner
95
+ * may hold several accounts for one mint, so they are summed.
96
+ */
97
+ export async function readSvmBalance(rpcUrl, asset, owner) {
98
+ if (!asset.mint) {
99
+ const lamports = await rpc(rpcUrl, 'getBalance', [owner]);
100
+ const value = lamports?.value ?? 0;
101
+ return {
102
+ asset,
103
+ amount: BigInt(value),
104
+ decimals: asset.decimals ?? SOL_DECIMALS,
105
+ symbol: asset.symbol ?? 'SOL',
106
+ };
107
+ }
108
+ const result = await rpc(rpcUrl, 'getTokenAccountsByOwner', [
109
+ owner,
110
+ { mint: asset.mint },
111
+ { encoding: 'jsonParsed' },
112
+ ]);
113
+ const accounts = result?.value ?? [];
114
+ let amount = 0n;
115
+ let decimals = asset.decimals ?? 0;
116
+ for (const entry of accounts) {
117
+ const info = entry?.account?.data?.parsed?.info;
118
+ const token = info?.tokenAmount;
119
+ if (typeof token?.amount === 'string') {
120
+ amount += BigInt(token.amount);
121
+ }
122
+ if (asset.decimals === undefined && typeof token?.decimals === 'number') {
123
+ decimals = token.decimals;
124
+ }
125
+ }
126
+ return { asset, amount, decimals, symbol: asset.symbol };
127
+ }
128
+ /**
129
+ * Formats an amount for display, without ever making it a float.
130
+ *
131
+ * String arithmetic on the integer, not a division: the whole reason the
132
+ * amount is a bigint is that the moment it becomes a Number it stops being
133
+ * exact, and a balance is shown next to a charge the payer is about to
134
+ * approve.
135
+ */
136
+ export function formatUnits(amount, decimals) {
137
+ const negative = amount < 0n;
138
+ const digits = (negative ? -amount : amount).toString().padStart(decimals + 1, '0');
139
+ const whole = digits.slice(0, digits.length - decimals);
140
+ const fraction = decimals > 0
141
+ ? digits.slice(digits.length - decimals).replace(/0+$/, '')
142
+ : '';
143
+ const sign = negative ? '-' : '';
144
+ return fraction ? `${sign}${whole}.${fraction}` : `${sign}${whole}`;
145
+ }
146
+ //# sourceMappingURL=balance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance.js","sourceRoot":"","sources":["../src/balance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Base58, encode only.
3
+ *
4
+ * Here for one reason: a wallet reached through the Wallet Standard returns a
5
+ * transaction signature as raw bytes, and every other part of this system
6
+ * names a Solana transaction by its base58 string. Nothing else in this
7
+ * bundle encodes anything; the transaction itself arrives already built.
8
+ *
9
+ * Big-integer division by repeated subtraction over the byte array, because
10
+ * 64 bytes exceeds what a JavaScript number can hold and a checkout page
11
+ * should not ship a bignum library to convert one signature.
12
+ */
13
+ export declare function base58Encode(bytes: Uint8Array): string;
14
+ /** Decodes the base64 the API sends raw bytes in. */
15
+ export declare function fromBase64(value: string): Uint8Array;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base58.d.ts","sourceRoot":"","sources":["../src/base58.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CA+BtD;AAED,qDAAqD;AACrD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAOpD"}
package/dist/base58.js ADDED
@@ -0,0 +1,52 @@
1
+ const ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
2
+ /**
3
+ * Base58, encode only.
4
+ *
5
+ * Here for one reason: a wallet reached through the Wallet Standard returns a
6
+ * transaction signature as raw bytes, and every other part of this system
7
+ * names a Solana transaction by its base58 string. Nothing else in this
8
+ * bundle encodes anything; the transaction itself arrives already built.
9
+ *
10
+ * Big-integer division by repeated subtraction over the byte array, because
11
+ * 64 bytes exceeds what a JavaScript number can hold and a checkout page
12
+ * should not ship a bignum library to convert one signature.
13
+ */
14
+ export function base58Encode(bytes) {
15
+ if (bytes.length === 0) {
16
+ return '';
17
+ }
18
+ // Leading zero bytes are not part of the number and would be lost in the
19
+ // division, so they are counted off first and written back as '1's.
20
+ let zeros = 0;
21
+ while (zeros < bytes.length && bytes[zeros] === 0) {
22
+ zeros++;
23
+ }
24
+ const digits = [];
25
+ for (let i = zeros; i < bytes.length; i++) {
26
+ let carry = bytes[i];
27
+ for (let j = 0; j < digits.length; j++) {
28
+ carry += digits[j] << 8;
29
+ digits[j] = carry % 58;
30
+ carry = (carry / 58) | 0;
31
+ }
32
+ while (carry > 0) {
33
+ digits.push(carry % 58);
34
+ carry = (carry / 58) | 0;
35
+ }
36
+ }
37
+ let out = '1'.repeat(zeros);
38
+ for (let i = digits.length - 1; i >= 0; i--) {
39
+ out += ALPHABET[digits[i]];
40
+ }
41
+ return out;
42
+ }
43
+ /** Decodes the base64 the API sends raw bytes in. */
44
+ export function fromBase64(value) {
45
+ const binary = atob(value);
46
+ const out = new Uint8Array(binary.length);
47
+ for (let i = 0; i < binary.length; i++) {
48
+ out[i] = binary.charCodeAt(i);
49
+ }
50
+ return out;
51
+ }
52
+ //# sourceMappingURL=base58.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base58.js","sourceRoot":"","sources":["../src/base58.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,4DAA4D,CAAA;AAE7E;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAAC,KAAiB;IAC7C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,CAAA;IACV,CAAC;IAED,yEAAyE;IACzE,oEAAoE;IACpE,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,OAAO,KAAK,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,KAAK,EAAE,CAAA;IACR,CAAC;IAED,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,IAAI,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;YACvB,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE,CAAA;YACtB,KAAK,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC,CAAA;QACzB,CAAC;QACD,OAAO,KAAK,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,CAAA;YACvB,KAAK,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,CAAC,CAAA;QACzB,CAAC;IACF,CAAC;IAED,IAAI,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC3B,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;IAC3B,CAAC;IACD,OAAO,GAAG,CAAA;AACX,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,UAAU,CAAC,KAAa;IACvC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;IAC1B,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;IAC9B,CAAC;IACD,OAAO,GAAG,CAAA;AACX,CAAC"}