remitmd 0.1.4 → 0.1.6
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.
- checksums.yaml +4 -4
- data/README.md +3 -14
- data/lib/remitmd/errors.rb +2 -2
- data/lib/remitmd/http.rb +9 -4
- data/lib/remitmd/mock.rb +2 -3
- data/lib/remitmd/models.rb +9 -9
- data/lib/remitmd/wallet.rb +47 -56
- data/lib/remitmd.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 77a3a0333d3f1afc8315ad1d523bc9adb70e74d2f5af29bc20b608233b0f67b1
|
|
4
|
+
data.tar.gz: b04b273b6340c25f8adcc5e755e99a4f32c9e804aec91d2e28058a66f507e9e9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3e343856eb6688f7a5bee1a10fa85ae119e9ac548eeedfb4bb95a21f4a5565d8ad4921efccfcad940f3f8a89fb7a0fd313243c7dd511f132c0540b69e05b2f82
|
|
7
|
+
data.tar.gz: 284848e90b0c9c53bc80a07fa7a2bc90ea7f3e1afef282b10308a9fc5805b9c750392d75a6055bf152660d15a1b3948d06fddbf179f5daf2ae3b586f0e18a35a
|
data/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# remit.md Ruby SDK
|
|
2
2
|
|
|
3
|
+
> [Skill MD](https://remit.md) · [Docs](https://remit.md/docs) · [Agent Spec](https://remit.md/agent.md)
|
|
4
|
+
|
|
3
5
|
Universal payment protocol for AI agents — Ruby client library.
|
|
4
6
|
|
|
5
7
|
[](https://github.com/remit-md/sdk/actions/workflows/ci.yml)
|
|
@@ -38,7 +40,7 @@ Or from environment variables:
|
|
|
38
40
|
```ruby
|
|
39
41
|
wallet = Remitmd::RemitWallet.from_env
|
|
40
42
|
# Requires: REMITMD_PRIVATE_KEY
|
|
41
|
-
# Optional: REMITMD_CHAIN (default: "base"), REMITMD_API_URL
|
|
43
|
+
# Optional: REMITMD_CHAIN (default: "base"), REMITMD_API_URL
|
|
42
44
|
```
|
|
43
45
|
|
|
44
46
|
Permits are auto-signed. Every payment method fetches the on-chain USDC nonce, signs an EIP-2612 permit, and includes it automatically.
|
|
@@ -267,19 +269,6 @@ permit = wallet.sign_usdc_permit(
|
|
|
267
269
|
tx = wallet.pay("0xRecipient...", 5.00, permit: permit)
|
|
268
270
|
```
|
|
269
271
|
|
|
270
|
-
### Custom RPC URL
|
|
271
|
-
|
|
272
|
-
Override the JSON-RPC endpoint used for nonce fetching:
|
|
273
|
-
|
|
274
|
-
```ruby
|
|
275
|
-
wallet = Remitmd::RemitWallet.new(
|
|
276
|
-
private_key: key,
|
|
277
|
-
chain: "base_sepolia",
|
|
278
|
-
rpc_url: "https://your-rpc-provider.com/v1/base-sepolia"
|
|
279
|
-
)
|
|
280
|
-
# Or via environment: REMITMD_RPC_URL
|
|
281
|
-
```
|
|
282
|
-
|
|
283
272
|
## License
|
|
284
273
|
|
|
285
274
|
MIT — see [LICENSE](LICENSE)
|
data/lib/remitmd/errors.rb
CHANGED
|
@@ -30,12 +30,12 @@ module Remitmd
|
|
|
30
30
|
SERVER_ERROR = "SERVER_ERROR"
|
|
31
31
|
NONCE_REUSED = "NONCE_REUSED"
|
|
32
32
|
SIGNATURE_INVALID = "SIGNATURE_INVALID"
|
|
33
|
-
|
|
33
|
+
ESCROW_ALREADY_COMPLETED = "ESCROW_ALREADY_COMPLETED"
|
|
34
34
|
ESCROW_EXPIRED = "ESCROW_EXPIRED"
|
|
35
35
|
TAB_LIMIT_EXCEEDED = "TAB_LIMIT_EXCEEDED"
|
|
36
36
|
BOUNTY_ALREADY_AWARDED = "BOUNTY_ALREADY_AWARDED"
|
|
37
37
|
STREAM_NOT_ACTIVE = "STREAM_NOT_ACTIVE"
|
|
38
|
-
|
|
38
|
+
DEPOSIT_ALREADY_RESOLVED = "DEPOSIT_ALREADY_RESOLVED"
|
|
39
39
|
USDC_TRANSFER_FAILED = "USDC_TRANSFER_FAILED"
|
|
40
40
|
CHAIN_UNAVAILABLE = "CHAIN_UNAVAILABLE"
|
|
41
41
|
|
data/lib/remitmd/http.rb
CHANGED
|
@@ -8,9 +8,11 @@ require "openssl"
|
|
|
8
8
|
|
|
9
9
|
module Remitmd
|
|
10
10
|
# Chain configuration: maps chain names to (api_url, chain_id) pairs.
|
|
11
|
+
# Canonical keys use hyphens; underscored variants are accepted as aliases.
|
|
11
12
|
CHAIN_CONFIG = {
|
|
12
|
-
"base" => { url: "https://remit.md/api/v1",
|
|
13
|
-
"
|
|
13
|
+
"base" => { url: "https://remit.md/api/v1", chain_id: 8453 },
|
|
14
|
+
"base-sepolia" => { url: "https://testnet.remit.md/api/v1", chain_id: 84532 },
|
|
15
|
+
"base_sepolia" => { url: "https://testnet.remit.md/api/v1", chain_id: 84532 },
|
|
14
16
|
}.freeze
|
|
15
17
|
|
|
16
18
|
# HTTP transport layer. Signs each request with EIP-712 auth headers and
|
|
@@ -40,9 +42,11 @@ module Remitmd
|
|
|
40
42
|
|
|
41
43
|
def request(method, path, body)
|
|
42
44
|
attempt = 0
|
|
45
|
+
# Generate idempotency key once per request (stable across retries).
|
|
46
|
+
idempotency_key = (method == :post || method == :put || method == :patch) ? SecureRandom.uuid : nil
|
|
43
47
|
begin
|
|
44
48
|
attempt += 1
|
|
45
|
-
req = build_request(method, path, body)
|
|
49
|
+
req = build_request(method, path, body, idempotency_key)
|
|
46
50
|
resp = @http.request(req)
|
|
47
51
|
handle_response(resp, path)
|
|
48
52
|
rescue RemitError => e
|
|
@@ -58,7 +62,7 @@ module Remitmd
|
|
|
58
62
|
end
|
|
59
63
|
end
|
|
60
64
|
|
|
61
|
-
def build_request(method, path, body)
|
|
65
|
+
def build_request(method, path, body, idempotency_key = nil)
|
|
62
66
|
full_path = "#{@uri.path}#{path}"
|
|
63
67
|
req = case method
|
|
64
68
|
when :get then Net::HTTP::Get.new(full_path)
|
|
@@ -81,6 +85,7 @@ module Remitmd
|
|
|
81
85
|
req["X-Remit-Nonce"] = nonce_hex
|
|
82
86
|
req["X-Remit-Timestamp"] = timestamp.to_s
|
|
83
87
|
req["X-Remit-Signature"] = signature
|
|
88
|
+
req["X-Idempotency-Key"] = idempotency_key if idempotency_key
|
|
84
89
|
|
|
85
90
|
if body
|
|
86
91
|
req.body = body.to_json
|
data/lib/remitmd/mock.rb
CHANGED
|
@@ -148,7 +148,6 @@ module Remitmd
|
|
|
148
148
|
"deposit" => "0xMockDeposit00000000000000000000000001",
|
|
149
149
|
"fee_calculator" => "0xMockFeeCalc0000000000000000000000001",
|
|
150
150
|
"key_registry" => "0xMockKeyReg000000000000000000000000001",
|
|
151
|
-
"arbitration" => "0xMockArbitr000000000000000000000000001",
|
|
152
151
|
}
|
|
153
152
|
|
|
154
153
|
# Balance
|
|
@@ -200,7 +199,7 @@ module Remitmd
|
|
|
200
199
|
in ["POST", path] if path.end_with?("/release") && path.include?("/escrows/")
|
|
201
200
|
id = extract_id(path, "/escrows/", "/release")
|
|
202
201
|
esc = @state[:escrows].fetch(id) { raise not_found(RemitError::ESCROW_NOT_FOUND, id) }
|
|
203
|
-
new_esc = update_escrow(esc, status: EscrowStatus::
|
|
202
|
+
new_esc = update_escrow(esc, status: EscrowStatus::COMPLETED)
|
|
204
203
|
@state[:escrows][id] = new_esc
|
|
205
204
|
tx = make_tx(from: esc.payer, to: esc.payee, amount: esc.amount)
|
|
206
205
|
@state[:transactions] << tx
|
|
@@ -269,7 +268,7 @@ module Remitmd
|
|
|
269
268
|
in ["POST", path] if path.end_with?("/close") && path.include?("/tabs/")
|
|
270
269
|
id = extract_id(path, "/tabs/", "/close")
|
|
271
270
|
tab = @state[:tabs].fetch(id) { raise not_found(RemitError::TAB_NOT_FOUND, id) }
|
|
272
|
-
new_tab = update_tab(tab, status: TabStatus::
|
|
271
|
+
new_tab = update_tab(tab, status: TabStatus::CLOSED)
|
|
273
272
|
@state[:tabs][id] = new_tab
|
|
274
273
|
tab_hash(new_tab)
|
|
275
274
|
|
data/lib/remitmd/models.rb
CHANGED
|
@@ -16,29 +16,30 @@ module Remitmd
|
|
|
16
16
|
module EscrowStatus
|
|
17
17
|
PENDING = "pending"
|
|
18
18
|
FUNDED = "funded"
|
|
19
|
-
|
|
19
|
+
ACTIVE = "active"
|
|
20
|
+
COMPLETED = "completed"
|
|
20
21
|
CANCELLED = "cancelled"
|
|
21
|
-
|
|
22
|
+
FAILED = "failed"
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
module TabStatus
|
|
25
26
|
OPEN = "open"
|
|
26
27
|
CLOSED = "closed"
|
|
27
|
-
|
|
28
|
+
EXPIRED = "expired"
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
module StreamStatus
|
|
31
32
|
ACTIVE = "active"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
CANCELLED = "cancelled"
|
|
33
|
+
CLOSED = "closed"
|
|
34
|
+
COMPLETED = "completed"
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
module BountyStatus
|
|
38
38
|
OPEN = "open"
|
|
39
|
+
CLAIMED = "claimed"
|
|
39
40
|
AWARDED = "awarded"
|
|
40
41
|
EXPIRED = "expired"
|
|
41
|
-
|
|
42
|
+
CANCELLED = "cancelled"
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
module DepositStatus
|
|
@@ -116,12 +117,11 @@ module Remitmd
|
|
|
116
117
|
@deposit = h["deposit"]
|
|
117
118
|
@fee_calculator = h["fee_calculator"]
|
|
118
119
|
@key_registry = h["key_registry"]
|
|
119
|
-
@arbitration = h["arbitration"]
|
|
120
120
|
@relayer = h["relayer"]
|
|
121
121
|
end
|
|
122
122
|
|
|
123
123
|
attr_reader :chain_id, :usdc, :router, :escrow, :tab, :stream,
|
|
124
|
-
:bounty, :deposit, :fee_calculator, :key_registry,
|
|
124
|
+
:bounty, :deposit, :fee_calculator, :key_registry,
|
|
125
125
|
:relayer
|
|
126
126
|
end
|
|
127
127
|
|
data/lib/remitmd/wallet.rb
CHANGED
|
@@ -2,25 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
require "bigdecimal"
|
|
4
4
|
require "bigdecimal/util"
|
|
5
|
-
require "net/http"
|
|
6
|
-
require "uri"
|
|
7
5
|
require "json"
|
|
8
6
|
|
|
9
7
|
module Remitmd
|
|
10
8
|
# Known USDC contract addresses per chain (EIP-2612 compatible).
|
|
11
9
|
USDC_ADDRESSES = {
|
|
12
|
-
"base-sepolia" => "
|
|
10
|
+
"base-sepolia" => "0x2d846325766921935f37d5b4478196d3ef93707c",
|
|
13
11
|
"base" => "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
14
12
|
"localhost" => "0x5FbDB2315678afecb367f032d93F642f64180aa3",
|
|
15
13
|
}.freeze
|
|
16
14
|
|
|
17
|
-
# Default JSON-RPC endpoints per chain (for nonce fetching).
|
|
18
|
-
DEFAULT_RPC_URLS = {
|
|
19
|
-
"base-sepolia" => "https://sepolia.base.org",
|
|
20
|
-
"base" => "https://mainnet.base.org",
|
|
21
|
-
"localhost" => "http://127.0.0.1:8545",
|
|
22
|
-
}.freeze
|
|
23
|
-
|
|
24
15
|
# Primary remit.md client. All payment operations are methods on RemitWallet.
|
|
25
16
|
#
|
|
26
17
|
# @example Quickstart
|
|
@@ -39,16 +30,14 @@ module Remitmd
|
|
|
39
30
|
# @param signer [Signer, nil] custom signer (pass instead of private_key)
|
|
40
31
|
# @param chain [String] chain name — "base", "base_sepolia"
|
|
41
32
|
# @param api_url [String, nil] override API base URL
|
|
42
|
-
# @param rpc_url [String, nil] override JSON-RPC URL for on-chain queries
|
|
43
33
|
# @param transport [Object, nil] inject mock transport (used by MockRemit)
|
|
44
|
-
def initialize(private_key: nil, signer: nil, chain: "base", api_url: nil, router_address: nil,
|
|
34
|
+
def initialize(private_key: nil, signer: nil, chain: "base", api_url: nil, router_address: nil, transport: nil)
|
|
45
35
|
if transport
|
|
46
36
|
# MockRemit path: transport + signer injected directly
|
|
47
37
|
@signer = signer
|
|
48
38
|
@transport = transport
|
|
49
39
|
@chain_key = "base-sepolia"
|
|
50
40
|
@chain_id = ChainId::BASE_SEPOLIA
|
|
51
|
-
@rpc_url = DEFAULT_RPC_URLS["base-sepolia"]
|
|
52
41
|
@mock_mode = true
|
|
53
42
|
return
|
|
54
43
|
end
|
|
@@ -61,7 +50,7 @@ module Remitmd
|
|
|
61
50
|
end
|
|
62
51
|
|
|
63
52
|
@signer = signer || PrivateKeySigner.new(private_key)
|
|
64
|
-
# Normalize chain key for USDC
|
|
53
|
+
# Normalize chain key for USDC lookups (underscore → hyphen).
|
|
65
54
|
@chain_key = chain.tr("_", "-")
|
|
66
55
|
# Normalize to the base chain name (strip testnet suffix) for use in pay body.
|
|
67
56
|
# The server accepts "base" — not "base_sepolia" etc.
|
|
@@ -72,7 +61,6 @@ module Remitmd
|
|
|
72
61
|
base_url = api_url || cfg[:url]
|
|
73
62
|
@chain_id = cfg[:chain_id]
|
|
74
63
|
router_address ||= ""
|
|
75
|
-
@rpc_url = rpc_url || ENV["REMITMD_RPC_URL"] || DEFAULT_RPC_URLS[@chain_key] || DEFAULT_RPC_URLS["base-sepolia"]
|
|
76
64
|
@transport = HttpTransport.new(
|
|
77
65
|
base_url: base_url,
|
|
78
66
|
signer: @signer,
|
|
@@ -82,14 +70,19 @@ module Remitmd
|
|
|
82
70
|
end
|
|
83
71
|
|
|
84
72
|
# Build a RemitWallet from environment variables.
|
|
85
|
-
# Reads: REMITMD_PRIVATE_KEY
|
|
73
|
+
# Reads: REMITMD_KEY (primary) or REMITMD_PRIVATE_KEY (deprecated fallback),
|
|
74
|
+
# REMITMD_CHAIN, REMITMD_API_URL, REMITMD_ROUTER_ADDRESS.
|
|
86
75
|
def self.from_env
|
|
87
|
-
key
|
|
76
|
+
key = ENV["REMITMD_KEY"] || ENV["REMITMD_PRIVATE_KEY"]
|
|
77
|
+
if ENV["REMITMD_PRIVATE_KEY"] && !ENV["REMITMD_KEY"]
|
|
78
|
+
warn "[remitmd] REMITMD_PRIVATE_KEY is deprecated, use REMITMD_KEY instead"
|
|
79
|
+
end
|
|
80
|
+
raise ArgumentError, "REMITMD_KEY not set" unless key
|
|
81
|
+
|
|
88
82
|
chain = ENV.fetch("REMITMD_CHAIN", "base")
|
|
89
83
|
api_url = ENV["REMITMD_API_URL"]
|
|
90
84
|
router_address = ENV["REMITMD_ROUTER_ADDRESS"]
|
|
91
|
-
|
|
92
|
-
new(private_key: key, chain: chain, api_url: api_url, router_address: router_address, rpc_url: rpc_url)
|
|
85
|
+
new(private_key: key, chain: chain, api_url: api_url, router_address: router_address)
|
|
93
86
|
end
|
|
94
87
|
|
|
95
88
|
# The Ethereum address associated with this wallet.
|
|
@@ -350,7 +343,15 @@ module Remitmd
|
|
|
350
343
|
# @param usdc_address [String, nil] override the USDC contract address
|
|
351
344
|
# @return [PermitSignature]
|
|
352
345
|
def sign_usdc_permit(spender, value, deadline, nonce = 0, usdc_address: nil)
|
|
353
|
-
usdc_addr = usdc_address || USDC_ADDRESSES[@chain_key]
|
|
346
|
+
usdc_addr = usdc_address || USDC_ADDRESSES[@chain_key]
|
|
347
|
+
if usdc_addr.nil? || usdc_addr.empty?
|
|
348
|
+
raise RemitError.new(
|
|
349
|
+
RemitError::INVALID_ADDRESS,
|
|
350
|
+
"No USDC address configured for chain #{@chain_key.inspect}. " \
|
|
351
|
+
"Valid chains: #{USDC_ADDRESSES.keys.join(", ")}",
|
|
352
|
+
context: { chain: @chain_key }
|
|
353
|
+
)
|
|
354
|
+
end
|
|
354
355
|
chain_id = @chain_id || ChainId::BASE_SEPOLIA
|
|
355
356
|
|
|
356
357
|
# Domain separator for USDC (EIP-2612)
|
|
@@ -397,8 +398,16 @@ module Remitmd
|
|
|
397
398
|
# @param deadline [Integer, nil] optional Unix timestamp; defaults to 1 hour from now
|
|
398
399
|
# @return [PermitSignature]
|
|
399
400
|
def sign_permit(spender, amount, deadline: nil)
|
|
400
|
-
usdc_addr = USDC_ADDRESSES[@chain_key]
|
|
401
|
-
|
|
401
|
+
usdc_addr = USDC_ADDRESSES[@chain_key]
|
|
402
|
+
if usdc_addr.nil? || usdc_addr.empty?
|
|
403
|
+
raise RemitError.new(
|
|
404
|
+
RemitError::INVALID_ADDRESS,
|
|
405
|
+
"No USDC address configured for chain #{@chain_key.inspect}. " \
|
|
406
|
+
"Valid chains: #{USDC_ADDRESSES.keys.join(", ")}",
|
|
407
|
+
context: { chain: @chain_key }
|
|
408
|
+
)
|
|
409
|
+
end
|
|
410
|
+
nonce = fetch_permit_nonce(usdc_addr)
|
|
402
411
|
dl = deadline || (Time.now.to_i + 3600)
|
|
403
412
|
raw = (amount * 1_000_000).round.to_i
|
|
404
413
|
sign_usdc_permit(spender, raw, dl, nonce, usdc_address: usdc_addr)
|
|
@@ -572,8 +581,8 @@ module Remitmd
|
|
|
572
581
|
begin
|
|
573
582
|
resolved = permit || auto_permit("relayer", 999_999_999.0)
|
|
574
583
|
body[:permit] = resolved.to_h
|
|
575
|
-
rescue StandardError
|
|
576
|
-
|
|
584
|
+
rescue StandardError => e
|
|
585
|
+
warn "[remitmd] create_fund_link: auto-permit failed: #{e.message}"
|
|
577
586
|
end
|
|
578
587
|
LinkResponse.new(@transport.post("/links/fund", body))
|
|
579
588
|
end
|
|
@@ -590,8 +599,8 @@ module Remitmd
|
|
|
590
599
|
begin
|
|
591
600
|
resolved = permit || auto_permit("relayer", 999_999_999.0)
|
|
592
601
|
body[:permit] = resolved.to_h
|
|
593
|
-
rescue StandardError
|
|
594
|
-
|
|
602
|
+
rescue StandardError => e
|
|
603
|
+
warn "[remitmd] create_withdraw_link: auto-permit failed: #{e.message}"
|
|
595
604
|
end
|
|
596
605
|
LinkResponse.new(@transport.post("/links/withdraw", body))
|
|
597
606
|
end
|
|
@@ -652,41 +661,23 @@ module Remitmd
|
|
|
652
661
|
|
|
653
662
|
# ─── Permit helpers ──────────────────────────────────────────────────
|
|
654
663
|
|
|
655
|
-
# Fetch the
|
|
656
|
-
# Uses JSON-RPC eth_call with selector 0x7ecebe00 (nonces(address)).
|
|
664
|
+
# Fetch the EIP-2612 permit nonce from the API.
|
|
657
665
|
# @param usdc_address [String] the USDC contract address
|
|
658
666
|
# @return [Integer] current nonce
|
|
659
|
-
def
|
|
667
|
+
def fetch_permit_nonce(usdc_address)
|
|
660
668
|
return 0 if @mock_mode
|
|
661
669
|
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
uri = URI.parse(@rpc_url)
|
|
672
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
|
673
|
-
http.use_ssl = (uri.scheme == "https")
|
|
674
|
-
http.read_timeout = 10
|
|
675
|
-
http.open_timeout = 5
|
|
676
|
-
|
|
677
|
-
req = Net::HTTP::Post.new(uri.request_uri)
|
|
678
|
-
req["Content-Type"] = "application/json"
|
|
679
|
-
req.body = payload.to_json
|
|
680
|
-
|
|
681
|
-
resp = http.request(req)
|
|
682
|
-
result = JSON.parse(resp.body)
|
|
683
|
-
|
|
684
|
-
if result["error"]
|
|
685
|
-
msg = result["error"].is_a?(Hash) ? result["error"]["message"] : result["error"].to_s
|
|
686
|
-
raise RemitError.new(RemitError::NETWORK_ERROR, "RPC error fetching nonce: #{msg}")
|
|
670
|
+
data = @transport.get("/status/#{address}")
|
|
671
|
+
nonce = data.is_a?(Hash) ? data["permit_nonce"] : nil
|
|
672
|
+
if nonce.nil?
|
|
673
|
+
raise RemitError.new(
|
|
674
|
+
RemitError::NETWORK_ERROR,
|
|
675
|
+
"permit_nonce not available from API for #{address}. " \
|
|
676
|
+
"Ensure the server supports the permit_nonce field in GET /api/v1/status.",
|
|
677
|
+
context: { address: address }
|
|
678
|
+
)
|
|
687
679
|
end
|
|
688
|
-
|
|
689
|
-
(result["result"] || "0x0").to_i(16)
|
|
680
|
+
nonce.to_i
|
|
690
681
|
end
|
|
691
682
|
|
|
692
683
|
# Auto-sign a permit for the given contract type and amount.
|
data/lib/remitmd.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: remitmd
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- remit.md
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-03-
|
|
11
|
+
date: 2026-03-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rspec
|