@orbi-wallet/sdk 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.d.ts CHANGED
@@ -8,10 +8,11 @@
8
8
  * const { walletAddress } = await orbi.connect();
9
9
  * const { signedXdr } = await orbi.signTransaction({ xdr });
10
10
  */
11
- import type { ConnectedWallet, EvmSignResult, OrbiChain, OrbiClientConfig, SignResult } from './types';
11
+ import type { ConnectedWallet, EvmSignatureResult, EvmSignResult, EvmTxParams, OrbiChain, OrbiClientConfig, SignResult } from './types';
12
12
  export declare class OrbiClient {
13
13
  private network;
14
14
  private chain;
15
+ private chainId?;
15
16
  constructor(config?: OrbiClientConfig);
16
17
  /** Wallet address from a previous `connect()`, restored from local storage. */
17
18
  getAddress(): string | null;
@@ -40,14 +41,29 @@ export declare class OrbiClient {
40
41
  walletAddress?: string;
41
42
  }): Promise<SignResult>;
42
43
  /**
43
- * Ask the user to review and approve a native-token (BOT) transfer on
44
- * BotChain. Signing and submission happen inside the Orbi popup where the
45
- * passkey lives so the dApp never touches a key. Returns the tx hash.
44
+ * Review and approve an EVM transaction native transfer or contract call.
45
+ * Signing and submission happen inside the Orbi popup (where the passkey
46
+ * lives), so the dApp never touches a key. Returns the tx hash.
47
+ * `value` is wei (decimal string); `data` is 0x calldata for contract calls.
46
48
  */
47
- signEvmTransaction(params: {
48
- to: string;
49
- value: string;
49
+ signEvmTransaction(params: EvmTxParams): Promise<EvmSignResult>;
50
+ /**
51
+ * Sign an arbitrary message (EIP-191 / personal_sign). This is what dApp
52
+ * login ("Sign-In With Ethereum") uses. Returns the 65-byte signature.
53
+ */
54
+ signMessage(params: {
55
+ message: string;
56
+ chainId?: number;
57
+ walletAddress?: string;
58
+ }): Promise<EvmSignatureResult>;
59
+ /**
60
+ * Sign EIP-712 typed data (eth_signTypedData_v4) — permits, listings, etc.
61
+ * `typedData` is the standard { domain, types, primaryType, message } object.
62
+ */
63
+ signTypedData(params: {
64
+ typedData: unknown;
65
+ chainId?: number;
50
66
  walletAddress?: string;
51
- }): Promise<EvmSignResult>;
67
+ }): Promise<EvmSignatureResult>;
52
68
  private openPopup;
53
69
  }
package/dist/client.js CHANGED
@@ -23,6 +23,7 @@ class OrbiClient {
23
23
  constructor(config = {}) {
24
24
  this.network = config.network ?? 'testnet';
25
25
  this.chain = config.chain ?? 'stellar';
26
+ this.chainId = config.chainId;
26
27
  }
27
28
  // ── Session ─────────────────────────────────────────────────────────────────
28
29
  /** Wallet address from a previous `connect()`, restored from local storage. */
@@ -108,19 +109,26 @@ class OrbiClient {
108
109
  });
109
110
  }
110
111
  /**
111
- * Ask the user to review and approve a native-token (BOT) transfer on
112
- * BotChain. Signing and submission happen inside the Orbi popup where the
113
- * passkey lives so the dApp never touches a key. Returns the tx hash.
112
+ * Review and approve an EVM transaction native transfer or contract call.
113
+ * Signing and submission happen inside the Orbi popup (where the passkey
114
+ * lives), so the dApp never touches a key. Returns the tx hash.
115
+ * `value` is wei (decimal string); `data` is 0x calldata for contract calls.
114
116
  */
115
117
  signEvmTransaction(params) {
116
118
  const walletAddress = params.walletAddress ?? this.getAddress() ?? undefined;
119
+ const chainId = params.chainId ?? this.chainId;
120
+ if (chainId === undefined)
121
+ throw new Error('chainId is required for EVM transactions');
117
122
  return this.openPopup({
118
123
  path: '/sign',
119
124
  params: {
120
125
  chain: 'botchain',
126
+ evmAction: 'tx',
127
+ chainId: String(chainId),
121
128
  to: params.to,
122
- value: params.value,
123
- network: this.network,
129
+ ...(params.value ? { value: params.value } : {}),
130
+ ...(params.data ? { data: params.data } : {}),
131
+ ...(params.gas ? { gas: params.gas } : {}),
124
132
  ...(walletAddress ? { walletAddress } : {}),
125
133
  },
126
134
  successType: 'orbi_evm_sent',
@@ -130,6 +138,52 @@ class OrbiClient {
130
138
  }),
131
139
  });
132
140
  }
141
+ /**
142
+ * Sign an arbitrary message (EIP-191 / personal_sign). This is what dApp
143
+ * login ("Sign-In With Ethereum") uses. Returns the 65-byte signature.
144
+ */
145
+ signMessage(params) {
146
+ const walletAddress = params.walletAddress ?? this.getAddress() ?? undefined;
147
+ const chainId = params.chainId ?? this.chainId;
148
+ return this.openPopup({
149
+ path: '/sign',
150
+ params: {
151
+ chain: 'botchain',
152
+ evmAction: 'message',
153
+ message: params.message,
154
+ ...(chainId !== undefined ? { chainId: String(chainId) } : {}),
155
+ ...(walletAddress ? { walletAddress } : {}),
156
+ },
157
+ successType: 'orbi_evm_signed',
158
+ mapSuccess: (msg) => ({
159
+ signature: msg.signature,
160
+ walletAddress: msg.walletAddress,
161
+ }),
162
+ });
163
+ }
164
+ /**
165
+ * Sign EIP-712 typed data (eth_signTypedData_v4) — permits, listings, etc.
166
+ * `typedData` is the standard { domain, types, primaryType, message } object.
167
+ */
168
+ signTypedData(params) {
169
+ const walletAddress = params.walletAddress ?? this.getAddress() ?? undefined;
170
+ const chainId = params.chainId ?? this.chainId;
171
+ return this.openPopup({
172
+ path: '/sign',
173
+ params: {
174
+ chain: 'botchain',
175
+ evmAction: 'typedData',
176
+ typedData: JSON.stringify(params.typedData),
177
+ ...(chainId !== undefined ? { chainId: String(chainId) } : {}),
178
+ ...(walletAddress ? { walletAddress } : {}),
179
+ },
180
+ successType: 'orbi_evm_signed',
181
+ mapSuccess: (msg) => ({
182
+ signature: msg.signature,
183
+ walletAddress: msg.walletAddress,
184
+ }),
185
+ });
186
+ }
133
187
  // ── Popup + postMessage handshake ───────────────────────────────────────────
134
188
  openPopup(req) {
135
189
  if (typeof window === 'undefined') {
package/dist/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
1
  export { OrbiClient } from './client';
2
- export type { ConnectedWallet, EvmSignResult, OrbiChain, OrbiClientConfig, OrbiNetwork, SignResult } from './types';
2
+ export { OrbiEIP1193Provider, createOrbiProvider } from './provider';
3
+ export type { OrbiProviderChain, OrbiProviderConfig } from './provider';
4
+ export type { ConnectedWallet, EvmSignatureResult, EvmSignResult, EvmTxParams, OrbiChain, OrbiClientConfig, OrbiNetwork, SignResult } from './types';
package/dist/index.js CHANGED
@@ -1,5 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OrbiClient = void 0;
3
+ exports.createOrbiProvider = exports.OrbiEIP1193Provider = exports.OrbiClient = void 0;
4
4
  var client_1 = require("./client");
5
5
  Object.defineProperty(exports, "OrbiClient", { enumerable: true, get: function () { return client_1.OrbiClient; } });
6
+ var provider_1 = require("./provider");
7
+ Object.defineProperty(exports, "OrbiEIP1193Provider", { enumerable: true, get: function () { return provider_1.OrbiEIP1193Provider; } });
8
+ Object.defineProperty(exports, "createOrbiProvider", { enumerable: true, get: function () { return provider_1.createOrbiProvider; } });
@@ -0,0 +1,47 @@
1
+ /**
2
+ * EIP-1193 provider for Orbi (EVM).
3
+ *
4
+ * Wraps OrbiClient so any standard EVM tooling — wagmi, ethers, viem,
5
+ * RainbowKit — can talk to an Orbi passkey wallet through the universal
6
+ * `request({ method, params })` interface. Signing methods open the Orbi popup
7
+ * (where the passkey lives); read methods are proxied to the chain's RPC.
8
+ */
9
+ import { OrbiClient } from './client';
10
+ import type { OrbiNetwork } from './types';
11
+ export interface OrbiProviderChain {
12
+ chainId: number;
13
+ rpcUrl: string;
14
+ }
15
+ export interface OrbiProviderConfig {
16
+ /** EVM chains this provider can serve, each with a JSON-RPC URL. */
17
+ chains: OrbiProviderChain[];
18
+ /** Active chain on construction. Defaults to the first chain. */
19
+ defaultChainId?: number;
20
+ network?: OrbiNetwork;
21
+ /** Reuse an existing client (and its session); one is created otherwise. */
22
+ client?: OrbiClient;
23
+ }
24
+ interface RequestArgs {
25
+ method: string;
26
+ params?: unknown[] | Record<string, unknown>;
27
+ }
28
+ type Listener = (...args: unknown[]) => void;
29
+ export declare class OrbiEIP1193Provider {
30
+ /** Lets dApps detect Orbi specifically (à la `isMetaMask`). */
31
+ readonly isOrbi = true;
32
+ private client;
33
+ private chains;
34
+ private chainId;
35
+ private listeners;
36
+ constructor(config: OrbiProviderConfig);
37
+ on(event: string, fn: Listener): this;
38
+ removeListener(event: string, fn: Listener): this;
39
+ private emit;
40
+ private currentAccounts;
41
+ request(args: RequestArgs): Promise<unknown>;
42
+ private rpc;
43
+ /** Convenience: forget the cached session (next eth_requestAccounts re-prompts). */
44
+ disconnect(): void;
45
+ }
46
+ export declare function createOrbiProvider(config: OrbiProviderConfig): OrbiEIP1193Provider;
47
+ export {};
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ /**
3
+ * EIP-1193 provider for Orbi (EVM).
4
+ *
5
+ * Wraps OrbiClient so any standard EVM tooling — wagmi, ethers, viem,
6
+ * RainbowKit — can talk to an Orbi passkey wallet through the universal
7
+ * `request({ method, params })` interface. Signing methods open the Orbi popup
8
+ * (where the passkey lives); read methods are proxied to the chain's RPC.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.OrbiEIP1193Provider = void 0;
12
+ exports.createOrbiProvider = createOrbiProvider;
13
+ const client_1 = require("./client");
14
+ function providerError(code, message) {
15
+ return Object.assign(new Error(message), { code });
16
+ }
17
+ // SDK popup rejections → EIP-1193's standard "user rejected" code (4001).
18
+ function mapRejection(err) {
19
+ const msg = err instanceof Error ? err.message : String(err);
20
+ if (/cancel|closed|reject/i.test(msg))
21
+ throw providerError(4001, 'User rejected the request');
22
+ throw err;
23
+ }
24
+ const isAddress = (v) => typeof v === 'string' && /^0x[0-9a-fA-F]{40}$/.test(v);
25
+ const toHexNum = (n) => '0x' + n.toString(16);
26
+ class OrbiEIP1193Provider {
27
+ constructor(config) {
28
+ /** Lets dApps detect Orbi specifically (à la `isMetaMask`). */
29
+ this.isOrbi = true;
30
+ this.listeners = {};
31
+ if (!config.chains?.length)
32
+ throw new Error('OrbiProvider requires at least one chain');
33
+ this.chains = new Map(config.chains.map((c) => [c.chainId, c.rpcUrl]));
34
+ this.chainId = config.defaultChainId ?? config.chains[0].chainId;
35
+ if (!this.chains.has(this.chainId))
36
+ throw new Error(`No RPC configured for chain ${this.chainId}`);
37
+ this.client =
38
+ config.client ?? new client_1.OrbiClient({ network: config.network, chain: 'botchain', chainId: this.chainId });
39
+ }
40
+ // ── EIP-1193 events ──────────────────────────────────────────────────────────
41
+ on(event, fn) { var _a; ((_a = this.listeners)[event] ?? (_a[event] = [])).push(fn); return this; }
42
+ removeListener(event, fn) {
43
+ this.listeners[event] = (this.listeners[event] ?? []).filter((l) => l !== fn);
44
+ return this;
45
+ }
46
+ emit(event, ...args) {
47
+ (this.listeners[event] ?? []).forEach((l) => l(...args));
48
+ }
49
+ currentAccounts() {
50
+ const addr = this.client.getAddress();
51
+ return addr && this.client.getChain() === 'botchain' ? [addr] : [];
52
+ }
53
+ // ── EIP-1193 request ─────────────────────────────────────────────────────────
54
+ async request(args) {
55
+ const { method } = args;
56
+ const params = (Array.isArray(args.params) ? args.params : []);
57
+ switch (method) {
58
+ case 'eth_requestAccounts': {
59
+ try {
60
+ const { walletAddress } = await this.client.connect({ chain: 'botchain' });
61
+ this.emit('connect', { chainId: toHexNum(this.chainId) });
62
+ this.emit('accountsChanged', [walletAddress]);
63
+ return [walletAddress];
64
+ }
65
+ catch (err) {
66
+ return mapRejection(err);
67
+ }
68
+ }
69
+ case 'eth_accounts':
70
+ return this.currentAccounts();
71
+ case 'eth_chainId':
72
+ return toHexNum(this.chainId);
73
+ case 'net_version':
74
+ return String(this.chainId);
75
+ case 'wallet_getPermissions':
76
+ case 'wallet_requestPermissions':
77
+ return [{ parentCapability: 'eth_accounts' }];
78
+ case 'wallet_switchEthereumChain': {
79
+ const target = parseInt(params[0]?.chainId, 16);
80
+ if (!this.chains.has(target)) {
81
+ throw providerError(4902, `Chain ${target} not configured in Orbi provider`);
82
+ }
83
+ this.chainId = target;
84
+ this.emit('chainChanged', toHexNum(target));
85
+ return null;
86
+ }
87
+ case 'wallet_addEthereumChain': {
88
+ const target = parseInt(params[0]?.chainId, 16);
89
+ if (!this.chains.has(target))
90
+ throw providerError(4902, `Chain ${target} not supported by Orbi`);
91
+ return null;
92
+ }
93
+ case 'eth_sendTransaction': {
94
+ const tx = (params[0] ?? {});
95
+ try {
96
+ const { txHash } = await this.client.signEvmTransaction({
97
+ to: tx.to,
98
+ value: tx.value ? BigInt(tx.value).toString() : undefined,
99
+ data: tx.data,
100
+ gas: tx.gas ? BigInt(tx.gas).toString() : undefined,
101
+ chainId: this.chainId,
102
+ });
103
+ return txHash;
104
+ }
105
+ catch (err) {
106
+ return mapRejection(err);
107
+ }
108
+ }
109
+ case 'personal_sign': {
110
+ // params: [message, address] (order varies by dApp — detect the address)
111
+ const message = (isAddress(params[0]) ? params[1] : params[0]);
112
+ try {
113
+ const { signature } = await this.client.signMessage({ message, chainId: this.chainId });
114
+ return signature;
115
+ }
116
+ catch (err) {
117
+ return mapRejection(err);
118
+ }
119
+ }
120
+ case 'eth_signTypedData_v4': {
121
+ // params: [address, typedData]
122
+ const raw = (isAddress(params[0]) ? params[1] : params[0]);
123
+ const typedData = typeof raw === 'string' ? JSON.parse(raw) : raw;
124
+ try {
125
+ const { signature } = await this.client.signTypedData({ typedData, chainId: this.chainId });
126
+ return signature;
127
+ }
128
+ catch (err) {
129
+ return mapRejection(err);
130
+ }
131
+ }
132
+ case 'eth_sign':
133
+ case 'eth_signTypedData':
134
+ case 'eth_signTypedData_v3':
135
+ throw providerError(4200, `${method} is not supported — use personal_sign or eth_signTypedData_v4`);
136
+ // Everything else (eth_call, eth_getBalance, eth_estimateGas,
137
+ // eth_getTransactionReceipt, eth_blockNumber, …) is a read — proxy to RPC.
138
+ default:
139
+ return this.rpc(method, params);
140
+ }
141
+ }
142
+ async rpc(method, params) {
143
+ const url = this.chains.get(this.chainId);
144
+ if (!url)
145
+ throw providerError(4901, `No RPC for chain ${this.chainId}`);
146
+ const res = await fetch(url, {
147
+ method: 'POST',
148
+ headers: { 'content-type': 'application/json' },
149
+ body: JSON.stringify({ jsonrpc: '2.0', id: Date.now(), method, params }),
150
+ });
151
+ const json = (await res.json());
152
+ if (json.error)
153
+ throw providerError(json.error.code ?? -32000, json.error.message ?? 'RPC error');
154
+ return json.result;
155
+ }
156
+ /** Convenience: forget the cached session (next eth_requestAccounts re-prompts). */
157
+ disconnect() {
158
+ this.client.disconnect();
159
+ this.emit('disconnect');
160
+ this.emit('accountsChanged', []);
161
+ }
162
+ }
163
+ exports.OrbiEIP1193Provider = OrbiEIP1193Provider;
164
+ function createOrbiProvider(config) {
165
+ return new OrbiEIP1193Provider(config);
166
+ }
package/dist/types.d.ts CHANGED
@@ -6,6 +6,8 @@ export interface OrbiClientConfig {
6
6
  network?: OrbiNetwork;
7
7
  /** Chain to connect on. Defaults to 'stellar'. */
8
8
  chain?: OrbiChain;
9
+ /** Default EVM chainId for signing/sending (per-call override available). */
10
+ chainId?: number;
9
11
  }
10
12
  export interface ConnectedWallet {
11
13
  walletAddress: string;
@@ -27,3 +29,15 @@ export interface EvmSignResult {
27
29
  txHash: string;
28
30
  walletAddress: string;
29
31
  }
32
+ export interface EvmSignatureResult {
33
+ signature: string;
34
+ walletAddress: string;
35
+ }
36
+ export interface EvmTxParams {
37
+ to: string;
38
+ value?: string;
39
+ data?: string;
40
+ gas?: string;
41
+ chainId?: number;
42
+ walletAddress?: string;
43
+ }
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export declare const SDK_NAME = "@orbi-wallet/sdk";
2
- export declare const SDK_VERSION = "0.1.2";
2
+ export declare const SDK_VERSION = "0.1.4";
package/dist/version.js CHANGED
@@ -3,4 +3,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SDK_VERSION = exports.SDK_NAME = void 0;
4
4
  // Generated by scripts/generate-version.js from package.json — do not edit.
5
5
  exports.SDK_NAME = "@orbi-wallet/sdk";
6
- exports.SDK_VERSION = "0.1.2";
6
+ exports.SDK_VERSION = "0.1.4";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orbi-wallet/sdk",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Orbi Smart Wallet SDK — connect any Stellar or BotChain dApp to Orbi passkey wallets",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",