Skip to content
This repository was archived by the owner on Dec 26, 2024. It is now read-only.

Commit 033fda0

Browse files
authored
Merge pull request #10 from abstraction-hq/develop
Support EIP-5792, Add RPC Provider.
2 parents c6fd4ce + 22048df commit 033fda0

14 files changed

Lines changed: 339 additions & 79 deletions

File tree

README.md

Lines changed: 82 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
Abstraction wallet SDK allow developers connect their Dapps to Abstraction Wallet via EIP-6963
44

55
## Install Abstraction Wallet SDK
6+
67
```sh
78
# yarn
89
yarn add @abstraction-hq/wallet-skd
@@ -14,25 +15,96 @@ npm install @abstraction-hq/wallet-sdk
1415
```
1516

1617
## Basic Usage
17-
### Use with EIP-6963
18-
1. Initialize Wallet
18+
19+
### Init provider with EIP-6963
20+
1921
```typescript
20-
import { initAbstractionWallet } from "@abstraction-hq/wallet-sdk"
22+
import { initAbstractionWallet } from "@abstraction-hq/wallet-sdk";
2123

22-
initAbstractionWallet()
24+
initAbstractionWallet();
2325
```
2426

25-
### Use with Provider
26-
1. Create provider
27+
### Create provider
28+
2729
```typescript
28-
import { createAbstractionProvider } from "@abstraction-hq/wallet-sdk"
30+
import { createAbstractionProvider } from "@abstraction-hq/wallet-sdk";
2931

30-
const provider = createAbstractionProvider()
32+
const provider = createAbstractionProvider();
3133
```
3234

33-
2 Use provider
35+
### Use provider
36+
1. Connect Wallet
37+
3438
```typescript
3539
const addresses = provider.request({
36-
method: 'eth_requestAccounts',
40+
method: "eth_requestAccounts",
41+
});
42+
```
43+
44+
2. Send Transaction
45+
46+
```typescript
47+
const txHash = await(window as any).abstraction.request({
48+
method: "eth_sendTransaction",
49+
params: [
50+
{
51+
from: address,
52+
to: address,
53+
value: 0,
54+
data,
55+
},
56+
],
57+
});
58+
```
59+
60+
3. Sending multiple calls
61+
```typescript
62+
const userOpHash = await(window as any).abstraction.request({
63+
method: "wallet_sendCalls",
64+
params: [
65+
{
66+
version: "1.0",
67+
chainId: "0x58",
68+
from: "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
69+
calls: [
70+
{
71+
to: "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
72+
value: "0x9184e72a",
73+
data: "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
74+
},
75+
{
76+
to: "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
77+
value: "0x9184e72a",
78+
data: "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
79+
},
80+
]
81+
}
82+
],
83+
});
84+
```
85+
86+
4. Get call status
87+
```typescript
88+
const callStatus = await(window as any).abstraction.request({
89+
method: "wallet_getCallsStatus",
90+
params: [
91+
userOpHash
92+
],
93+
});
94+
```
95+
96+
97+
5. Create contract
98+
```typescript
99+
const txHash = await(window as any).abstraction.request({
100+
method: "eth_sendTransaction",
101+
params: [
102+
{
103+
from: address,
104+
value: 0,
105+
data: CONTRACT_BYTECODE,
106+
},
107+
],
108+
salt: // Salt to create contract with create2 - account.nonce() if not provide
37109
});
38110
```

constants/address.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { Address } from "viem";
2+
3+
export const FACTORY: Address = "0xbC82703bDbE098773059957837016b8CA7374992"

constants/chain.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { defineChain } from "viem";
2+
3+
export const NETWORKS = "mainnet"
4+
5+
export const mainnet = defineChain({
6+
id: 88,
7+
name: "Viction Mainnet",
8+
nativeCurrency: {
9+
decimals: 18,
10+
name: "Viction",
11+
symbol: "VIC",
12+
},
13+
rpcUrls: {
14+
default: {
15+
http: ["https://rpc.viction.xyz"],
16+
webSocket: ["wss://ws.viction.xyz"],
17+
},
18+
},
19+
blockExplorers: {
20+
default: { name: "Explorer", url: "https://vicscan.xyz" },
21+
},
22+
testnet: true,
23+
});

constants/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
export * from "./supportedMethod"
2+
export * from "./chain"
3+
export * from "./address"
4+
25
export const KEY_URL = "https://wallet.abstraction.world"
6+
export const BUNDLER_URL = "https://wallet.abstraction.world/bundler"

constants/supportedMethod.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ export const supportedMethods: any = {
1919
],
2020
state: [
2121
// internal state
22-
'eth_chainId',
22+
// 'eth_chainId',
23+
'wallet_getCallsStatus',
2324
'eth_accounts',
2425
'eth_coinbase',
2526
'net_version',

index.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { IProvider } from "./types/provider/provider";
1+
import { IProvider, ProviderInput, EIP6963ProviderInfo } from "./types";
22
import { AbstractionProvider } from "./provider";
3-
import { EIP6963ProviderInfo } from "./types/provider/eip6963";
43

54
const announceProvider: Function = (provider: IProvider) => {
65
const info: EIP6963ProviderInfo = {
@@ -19,19 +18,22 @@ const announceProvider: Function = (provider: IProvider) => {
1918
window.removeEventListener("eip6963:requestProvider", () => {})
2019
};
2120

22-
const initAbstractionWallet: Function = (keyUrl?: string) => {
23-
const provider = new AbstractionProvider(keyUrl);
21+
const initAbstractionWallet: Function = (providerInput?: ProviderInput) => {
22+
const provider = new AbstractionProvider(providerInput);
2423
window.addEventListener("eip6963:requestProvider", () => {
2524
announceProvider(provider);
2625
});
2726
};
2827

29-
const createAbstractionProvider: Function = (keyUrl?: string): IProvider => {
30-
const provider = new AbstractionProvider(keyUrl);
28+
const createAbstractionProvider: Function = (providerInput?: ProviderInput): IProvider => {
29+
const provider = new AbstractionProvider(providerInput);
3130
return provider;
3231
};
3332

3433
export { initAbstractionWallet, createAbstractionProvider };
3534

3635
export * from "./communicator"
3736
export * from "./types"
37+
export * from "./constants"
38+
export * from "./provider"
39+
export * from "./utils"

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"dependencies": {
2727
"@types/chai": "^4.3.16",
2828
"@types/mocha": "^10.0.7",
29+
"axios": "^1.7.2",
2930
"chai": "^5.1.1",
3031
"eventemitter3": "^5.0.1",
3132
"mocha": "^10.6.0",

provider.ts renamed to provider/index.ts

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
import EventEmitter from "eventemitter3";
22
import { Address, toHex } from "viem";
3-
import { Communicator } from "./communicator/communicator";
4-
import { supportedMethods } from "./constants/supportedMethod";
3+
import { Communicator } from "../communicator/communicator";
4+
import { supportedMethods } from "../constants/supportedMethod";
55
import {
66
MethodCategory,
77
RequestArguments,
88
IProvider,
9-
} from "./types/provider/provider";
10-
import { Message } from "./types/communicator/message";
11-
import { getFavicon } from "./utils/getIcon";
9+
ProviderInput,
10+
} from "../types";
11+
import { Message } from "../types";
12+
import { getFavicon } from "../utils/getIcon";
13+
import RPCProvider from "./rpcProvider";
14+
import { BUNDLER_URL } from "../constants";
15+
import axios from "axios";
1216

1317
function determineMethodCategory(method: string): MethodCategory | undefined {
1418
for (const c in supportedMethods) {
@@ -21,22 +25,23 @@ function determineMethodCategory(method: string): MethodCategory | undefined {
2125
}
2226

2327
export class AbstractionProvider extends EventEmitter implements IProvider {
28+
public rpcProvider: RPCProvider;
2429
communicator: Communicator;
2530
accounts: Address[] = [];
2631
isAbstractionWallet: boolean = true;
2732
chainId: number = 89;
2833

29-
constructor(keyUrl?: string) {
34+
constructor(providerInput?: ProviderInput) {
3035
super();
31-
this.communicator = new Communicator(null, keyUrl);
36+
this.communicator = new Communicator(null, providerInput?.keyUrl);
37+
this.rpcProvider = new RPCProvider(providerInput?.rpcInput);
3238
}
3339

3440
public get connected() {
3541
return this.accounts.length > 0;
3642
}
3743

3844
public async request<T>(args: RequestArguments): Promise<T> {
39-
console.log("request", toHex(this.chainId));
4045
const methodCategory = determineMethodCategory(args.method) ?? "fetch";
4146
return (this.handlers as any)[methodCategory](args) as unknown as T;
4247
}
@@ -69,7 +74,7 @@ export class AbstractionProvider extends EventEmitter implements IProvider {
6974

7075
if (handshakeResponse.payload == "rejected") {
7176
reject("User rejected the connection");
72-
return
77+
return;
7378
}
7479

7580
this.accounts = handshakeResponse.payload as Address[];
@@ -100,22 +105,31 @@ export class AbstractionProvider extends EventEmitter implements IProvider {
100105
);
101106
if (signResponse.payload == "rejected") {
102107
reject("User rejected the connection");
103-
return
108+
return;
104109
}
105110
resolve(signResponse.payload);
106111
});
107112
},
108-
fetch: async (args: RequestArguments) => {},
113+
fetch: async (args: RequestArguments) => {
114+
return this.rpcProvider.requestRPC(args);
115+
},
109116
state: async (args: RequestArguments) => {
110117
switch (args.method) {
111-
case "eth_chainId":
112-
return toHex(this.chainId);
113118
case "eth_accounts":
114119
return this.accounts;
115120
case "eth_coinbase":
116121
return this.accounts[0];
117122
case "net_version":
118123
return "0x1";
124+
case "wallet_getCallsStatus":
125+
const data = {
126+
jsonrpc: "2.0",
127+
id: 1,
128+
method: "eth_getUserOperationReceipt",
129+
params: args.params,
130+
};
131+
const response = await axios.post(BUNDLER_URL, data);
132+
return response.data
119133
default:
120134
return undefined;
121135
}

provider/rpcProvider.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { RPCProviderInput } from "../types";
2+
import { mainnet } from "../constants";
3+
import { Chain, createPublicClient, defineChain, http, PublicClient } from "viem";
4+
5+
export default class RPCProvider {
6+
ethClient: PublicClient;
7+
8+
constructor(input?: RPCProviderInput) {
9+
let chain: Chain;
10+
if (input) {
11+
chain = defineChain({
12+
id: 88,
13+
name: "Viction Mainnet",
14+
nativeCurrency: {
15+
decimals: 18,
16+
name: "Viction",
17+
symbol: "VIC",
18+
},
19+
rpcUrls: {
20+
default: {
21+
http: [input.rpcUrl, "https://rpc.viction.xyz"],
22+
webSocket: [input.wsUrl, "wss://ws.viction.xyz"],
23+
},
24+
},
25+
blockExplorers: {
26+
default: { name: "Explorer", url: "https://vicscan.xyz" },
27+
},
28+
testnet: false,
29+
})
30+
} else {
31+
chain = mainnet
32+
}
33+
34+
// @ts-ignore
35+
this.ethClient = createPublicClient({
36+
chain: chain,
37+
transport: http()
38+
}) as PublicClient
39+
}
40+
41+
public async requestRPC(args: any) {
42+
return this.ethClient.request(args)
43+
}
44+
45+
public async getClient() {
46+
return this.ethClient
47+
}
48+
}

tests/provider.spec.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createAbstractionProvider } from "../index";
1+
import { createAbstractionProvider, IProvider } from "../index";
22

33
describe("Provider", () => {
44
it("Can create provider", async () => {
@@ -8,7 +8,30 @@ describe("Provider", () => {
88

99
it("Should override KeyURL", async() => {
1010
const keyUrl = "https://example.com";
11-
const provider = createAbstractionProvider(keyUrl);
11+
const provider = createAbstractionProvider({
12+
keyUrl
13+
});
1214
console.log(provider)
1315
})
16+
17+
it("Can request rpc", async () => {
18+
const provider: IProvider = createAbstractionProvider();
19+
console.log(provider.rpcProvider)
20+
const transaction = await provider.request({
21+
method: "eth_chainId",
22+
params: []
23+
})
24+
25+
console.log(transaction)
26+
})
27+
28+
it("Get call status", async () => {
29+
const provider: IProvider = createAbstractionProvider();
30+
const callStatus = await provider.request({
31+
method: "wallet_getCallsStatus",
32+
params: ["0x6b4f1165bfee4d6164ab44f52bd9e5bfa40da28491a33960ad9952aa3f202799"]
33+
})
34+
35+
console.log(callStatus)
36+
})
1437
})

0 commit comments

Comments
 (0)